2015-11-18 169 views
1

我正在尝试使用TCP将客户端的jpg文件发送到服务器。当图片到达服务器端时,我无法打开它,除了收到的图片大小高于发送的图片(发送= 880字节,收到= 894字节)。你们中的任何一个人都知道如何解决这个问题?这里是我的代码:通过TCP发送图片

客户端代码:

static int send_server_image(SOCKET sock){ 

    int n = 0; 
    int siz = 0; 
    FILE *picture; 
    char buf[50]; 
    char *s=""; 

    cout << "Getting image size" << endl; 
    picture = fopen("C:\\Users\\n.b\\Desktop\\c++\\TCP\\tcp_client_image_pp\\test.jpg", "r"); 
    fseek(picture, 0, SEEK_END); 
    siz = ftell(picture); 
    cout << siz << endl; // Output 880 

    cout << "Sending picture size to the server" << endl; 
    sprintf(buf, "%d", siz); 
    if((n = send(sock, buf, sizeof(buf), 0)) < 0) 
    { 
      perror("send_size()"); 
      exit(errno); 
    } 

    char Sbuf[siz]; 
    cout << "Sending the picture as byte array" << endl; 
    fseek(picture, 0, SEEK_END); 
    siz = ftell(picture); 
    fseek(picture, 0, SEEK_SET); //Going to the beginning of the file 

    while(!feof(picture)){ 
     fread(Sbuf, sizeof(char), sizeof(Sbuf), picture); 
     if((n = send(sock, Sbuf, sizeof(Sbuf), 0)) < 0) 
     { 
      perror("send_size()"); 
      exit(errno); 
     } 
     memset(Sbuf, 0, sizeof(Sbuf)); 
    } 
} 

服务器代码:

static int recv_client_image(SOCKET sock){ 

    int n = 0; 

    cout << "Reading image size" << endl; 
    char buf[50]; 
    int siz = 0; 
    if ((n = recv(sock, buf, sizeof(buf), 0) <0)){ 
     perror("recv_size()"); 
     exit(errno); 
    } 
    siz = atoi(buf); 
    cout << siz << endl; // 880 output 

    char Rbuffer[siz]; 
    cout << "Reading image byte array" << endl; 
    n = 0; 
    if ((n = recv(sock, Rbuffer, sizeof(Rbuffer), 0)) < 0){ 
     perror("recv_size()"); 
     exit(errno); 
    } 

    cout << "Converting byte array to image" << endl; 
    FILE *image; 
    image = fopen("recu.jpg", "w"); 
    fwrite(Rbuffer, sizeof(char), sizeof(Rbuffer), image); 
    fclose(image); 
    cout << "done" << endl; 

} 

谢谢。

+0

两个系统(发送者/接收者)是否具有相同的字节序?哪个排序?第一个recv呼叫接收了多少个字节?小于sizeof(buf)?添加更多调试输出或在调试器中运行并提供更多信息。 –

回答

0

您正在使用可变长度数组,它不是标准的C++(ref)。即使它被编译器接受,你也应该避免使用sizeof

而你在while(!feof(picture))有问题。您从文件中读取siz字节,没有任何错误并且没有设置eof标志。在第二次读取时,您读取0个字节并设置标志,但也发送另一个缓冲区。

而应该写:

while(!feof(picture)){ 
    n = fread(Sbuf, sizeof(char), siz, picture); 
    if (n > 0) { /* only send what has been read */ 
     if((n = send(sock, Sbuf, siz, 0)) < 0) /* or (better?) send(sock, Sbuf, n, 0) */ 
     { 
      perror("send_data()"); 
      exit(errno); 
     } 
    } 
    /* memset(Sbuf, 0, sizeof(Sbuf)); useless for binary data */ 
} 

相同的服务器部分:

if ((n = recv(sock, Rbuffer, siz, 0)) < 0){ 
    perror("recv_size()"); 
    exit(errno); 
} 

cout << "Converting byte array to image" << endl; 
FILE *image; 
image = fopen("recu.jpg", "w"); 
fwrite(Rbuffer, sizeof(char), siz, image); 
fclose(image); 

而且有错误的最后一个可能性,至少,如果你是在一个平台上,使之间的差异像Windows一样的文本和二进制文件是你忘记打开二进制模式的文件,这可能会打破JPG图像。因为在二进制文件的窗口上,字节0x10被视为新行(\n')并写为2个字节0x0d 0x10(\r\n)。

所以你必须打开rb模式的输入文件和wb模式的输出文件。

+0

你说的话看起来不错,但当我纠正我的代码时,我仍然遇到同样的问题... – EngineerN

+0

@EngineerN:上面的代码**不能接收超过siz字符,并且不能写更多...请参阅我的编辑另一个可能的原因 –

+0

我发现了这个问题。这些文件需要以二进制模式打开。请看下面的答案。感谢您的帮助 – EngineerN

0

已解决:

Serge Ballesta说得对的所有修正。但问题在于我打开文件的方式。

您需要二进制模式(“RB”阅读,“WB”为写),而不是默认的文本模式来打开文件。

客户:

picture = fopen("C:\\Users\\n.b\\Desktop\\c++\\TCP\\tcp_client_image_pp\\test.jpg", "rb"); 

服务器:

image = fopen("recu.jpg", "wb"); 

这是主要的问题。谢谢。