Sockets 通过C+发送图像+;套接字(Linux)
我正在尝试通过套接字发送文件。我创建了一个程序,它适用于文件类型,如.cpp、.txt和其他文本文件。但是二进制文件、图像(.jpg、.png)和压缩文件(如.zip和.rar)没有正确发送。我知道这与文件的大小无关,因为我使用大型.txt文件进行了测试。我不知道问题出在哪里,我正在接收发送的所有字节,但文件无法打开。大多数情况下,文件已损坏,无法查看。我在谷歌上搜索了一个解决方案,发现其他人也有同样的问题,但没有解决方案。所以,通过帮助我,你也在帮助任何需要解决方案的人 服务器代码:Sockets 通过C+发送图像+;套接字(Linux),sockets,Sockets,我正在尝试通过套接字发送文件。我创建了一个程序,它适用于文件类型,如.cpp、.txt和其他文本文件。但是二进制文件、图像(.jpg、.png)和压缩文件(如.zip和.rar)没有正确发送。我知道这与文件的大小无关,因为我使用大型.txt文件进行了测试。我不知道问题出在哪里,我正在接收发送的所有字节,但文件无法打开。大多数情况下,文件已损坏,无法查看。我在谷歌上搜索了一个解决方案,发现其他人也有同样的问题,但没有解决方案。所以,通过帮助我,你也在帮助任何需要解决方案的人 服务器代码: #inc
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main ( int agrc, char *argv[] )
{
/******** Program Variable Define & Initialize **********/
int Main_Socket; // Main Socket For Server
int Communication_Socket; // Socket For Special Clients
int Status; // Status Of Function
struct sockaddr_in Server_Address; // Address Of Server
struct sockaddr_in Client_Address;// Address Of Client That Communicate with Server
int Port;
char Buff[100] = "";
Port = atoi(argv[2]);
printf ("Server Communicating By Using Port %d\n", Port);
/******** Create A Socket To Communicate With Server **********/
Main_Socket = socket ( AF_INET, SOCK_STREAM, 0 );
if ( Main_Socket == -1 )
{
printf ("Sorry System Can Not Create Socket!\n");
}
/******** Create A Address For Server To Communicate **********/
Server_Address.sin_family = AF_INET;
Server_Address.sin_port = htons(Port);
Server_Address.sin_addr.s_addr = inet_addr(argv[1]);
/******** Bind Address To Socket **********/
Status = bind ( Main_Socket, (struct sockaddr*)&Server_Address, sizeof(Server_Address) );
if ( Status == -1 )
{
printf ("Sorry System Can Not Bind Address to The Socket!\n");
}
/******** Listen To The Port to Any Connection **********/
listen (Main_Socket,12);
socklen_t Lenght = sizeof (Client_Address);
while (1)
{
Communication_Socket = accept ( Main_Socket, (struct sockaddr*)&Client_Address, &Lenght );
if (!fork())
{
FILE *fp=fopen("recv.jpeg","w");
while(1)
{
char Buffer[2]="";
if (recv(Communication_Socket, Buffer, sizeof(Buffer), 0))
{
if ( strcmp (Buffer,"Hi") == 0 )
{
break;
}
else
{
fwrite(Buffer,sizeof(Buffer),1, fp);
}
}
}
fclose(fp);
send(Communication_Socket, "ACK" ,3,0);
printf("ACK Send");
exit(0);
}
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int agrc,char*argv[]
{
/********程序变量定义和初始化**********/
int Main_Socket;//服务器的主套接字
int通信_Socket;//特殊客户机的套接字
int Status;//函数的状态
服务器地址中的struct sockaddr\u;//服务器地址
客户端地址中的struct sockaddr\u;//与服务器通信的客户端地址
国际港口;
字符Buff[100]=“”;
端口=atoi(argv[2]);
printf(“使用端口%d\n进行通信的服务器”,端口);
/********创建与服务器通信的套接字**********/
Main_Socket=Socket(AF_INET,SOCK流,0);
如果(主_插槽==-1)
{
printf(“对不起,系统无法创建套接字!\n”);
}
/********为服务器创建通信地址**********/
服务器地址.sin\u family=AF\u INET;
服务器\地址.sin\端口=htons(端口);
Server_Address.sin_addr.s_addr=inet_addr(argv[1]);
/********将地址绑定到套接字**********/
状态=绑定(主套接字,(结构sockaddr*)和服务器地址,sizeof(服务器地址));
如果(状态==-1)
{
printf(“对不起,系统无法将地址绑定到套接字!\n”);
}
/********侦听任何连接的端口*********/
监听(主_插座,12);
socklen\u t Lenght=sizeof(客户地址);
而(1)
{
通信套接字=接受(主套接字,(结构sockaddr*)和客户端地址及长度);
如果(!fork())
{
文件*fp=fopen(“recv.jpeg”,“w”);
而(1)
{
字符缓冲区[2]=“”;
if(recv(通讯插座,缓冲区,大小(缓冲区),0))
{
如果(strcmp(缓冲区,“Hi”)==0)
{
打破
}
其他的
{
fwrite(缓冲区,sizeof(缓冲区),1,fp);
}
}
}
fclose(fp);
发送(通信插座,“确认”,3,0);
printf(“确认发送”);
出口(0);
}
}
返回0;
}
客户端代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main ( int agrc, char *argv[] )
{
int Socket;
struct sockaddr_in Server_Address;
Socket = socket ( AF_INET, SOCK_STREAM, 0 );
if ( Socket == -1 )
{
printf ("Can Not Create A Socket!");
}
int Port ;
Port = atoi(argv[2]);
Server_Address.sin_family = AF_INET;
Server_Address.sin_port = htons ( Port );
Server_Address.sin_addr.s_addr = inet_addr(argv[1]);
if ( Server_Address.sin_addr.s_addr == INADDR_NONE )
{
printf ( "Bad Address!" );
}
connect ( Socket, (struct sockaddr *)&Server_Address, sizeof (Server_Address) );
FILE *in = fopen("background.jpeg","r");
char Buffer[2] = "";
int len;
while ((len = fread(Buffer,sizeof(Buffer),1, in)) > 0)
{
send(Socket,Buffer,sizeof(Buffer),0);
}
send(Socket,"Hi",sizeof(Buffer),0);
char Buf[BUFSIZ];
recv(Socket, Buf, BUFSIZ, 0);
if ( strcmp (Buf,"ACK") == 0 )
{
printf("Recive ACK\n");
}
close (Socket);
fclose(in);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int agrc,char*argv[]
{
int插座;
服务器地址中的结构sockaddr\u;
Socket=Socket(AF_INET,SOCK_STREAM,0);
如果(套接字==-1)
{
printf(“无法创建套接字!”);
}
国际港口;
端口=atoi(argv[2]);
服务器地址.sin\u family=AF\u INET;
服务器\地址.sin\端口=htons(端口);
Server_Address.sin_addr.s_addr=inet_addr(argv[1]);
if(Server_Address.sin_addr.s_addr==INADDR_NONE)
{
printf(“坏地址!”);
}
连接(套接字,(结构sockaddr*)和服务器地址,sizeof(服务器地址));
文件*in=fopen(“background.jpeg”,“r”);
字符缓冲区[2]=“”;
内伦;
而((len=fread(Buffer,sizeof(Buffer),1,in))>0)
{
发送(套接字、缓冲区、sizeof(缓冲区)、0);
}
发送(Socket,“Hi”,sizeof(Buffer),0);
char Buf[BUFSIZ];
recv(插座,Buf,BUFSIZ,0);
如果(strcmp(Buf,“ACK”)==0)
{
printf(“接收确认”\n);
}
关闭(插座);
fclose(in);
返回0;
}
对于读取ascii文本文件,可以使用char
缓冲区
要读取二进制数据,您需要使用
无符号字符
,否则您的数据将被隐藏,因为二进制数据是无符号字节。首先,您应该尝试将缓冲区增加到更大的值。缓冲区越大,传输效率越高(只是不要夸大和消耗太多本地内存)
其次,您应该检查并使用读写函数返回的长度。在所有读写操作中,您只检查某个内容是否已读/写,但您应该在下一次写/读操作中使用此字节计数。例如,如果客户端报告它已读取1个字节,则应仅将1个字节写入磁盘。此外,如果从服务器读取了1024个字节,则应尝试将1024个字节写入磁盘,这可能不会在该调用中发生,并且可能需要再次调用写入来完成操作
我知道这听起来需要做很多工作,但这就是保证I/O操作的方法。所有的读写基本上都必须在自己的循环中完成。您确定二进制图像文件中没有字节序列
0x48 0x69
(“Hi”
)吗?您的读取循环将在收到该序列后立即终止。此外,您可以使用两个字节长的字符缓冲区调用strcmp()
,并且几乎可以肯定它没有空的终止字节('\0'
)
您还可以调查文件之间的差异?cmp
工具可以为您提供源和目标之间不同的字节列表
为了确保正确性,您一定要检查read()
,