Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 通过C+发送图像+;套接字(Linux)_Sockets - Fatal编程技术网

Sockets 通过C+发送图像+;套接字(Linux)

Sockets 通过C+发送图像+;套接字(Linux),sockets,Sockets,我正在尝试通过套接字发送文件。我创建了一个程序,它适用于文件类型,如.cpp、.txt和其他文本文件。但是二进制文件、图像(.jpg、.png)和压缩文件(如.zip和.rar)没有正确发送。我知道这与文件的大小无关,因为我使用大型.txt文件进行了测试。我不知道问题出在哪里,我正在接收发送的所有字节,但文件无法打开。大多数情况下,文件已损坏,无法查看。我在谷歌上搜索了一个解决方案,发现其他人也有同样的问题,但没有解决方案。所以,通过帮助我,你也在帮助任何需要解决方案的人 服务器代码: #inc

我正在尝试通过套接字发送文件。我创建了一个程序,它适用于文件类型,如.cpp、.txt和其他文本文件。但是二进制文件、图像(.jpg、.png)和压缩文件(如.zip和.rar)没有正确发送。我知道这与文件的大小无关,因为我使用大型.txt文件进行了测试。我不知道问题出在哪里,我正在接收发送的所有字节,但文件无法打开。大多数情况下,文件已损坏,无法查看。我在谷歌上搜索了一个解决方案,发现其他人也有同样的问题,但没有解决方案。所以,通过帮助我,你也在帮助任何需要解决方案的人

服务器代码:

#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()