日期:2014-05-16  浏览次数:20609 次

LINUX下socket传输多张图像数据,有误,丢帧严重
传输一张图像已成功,传输4张图像出错,每张图像32K,服务器端每次send 1k,发送32次。
for(m=0;m<num;m+=1024)           //传输jpg图像数据
             {
                      n=send(clientfd,buff+m,1024,0);
                      if(n==-1)  perror("send error");
                     printf("n:%d\n",n);  
               }
客户端每次recv 1K,接收32次。
for(m=0;m<MAXDATA;m+=1024)
                           {
                        n=recv(sockfd,buff+m,1024,0);
     if(n==-1)  perror("recv fail\n");
                        printf("n:%d\n",n); 
           }

服务器端可以发送出去数据,只能发送3帧,发送到第4帧,出错:send error: Connection reset by peer

客户端接收到的数据不全,有丢失。而且只能接收一帧,图像很模糊不清。

------解决方案--------------------
recv做下while处理吧,不能保证1024都收全呀
------解决方案--------------------
tcp是没有数据边界的,所以你的 m 不应该+= 1024, 而应该 m += n

按照你的程序写法,客户端很可能先于服务器关闭fd, 因为客户端可能错误的认为数据接收完了
------解决方案--------------------
这种连续收发的程序,最好带个帧头。帧尾,。客户端接收的时候,收取的数据先放一个缓冲区,按照帧头,帧尾来解析,解析到正确的一帧就重缓冲区删掉,,以此循环。。。这样可以避免粘包的问题。和缓解服务器端压力。
------解决方案--------------------
引用:
引用:
recv做下while处理吧,不能保证1024都收全呀

修改了下:
while(recvbytes<MAXDATA)
                        {
                        n=recv(sockfd,buff+recvbytes,MAXDATA,0);
if(n==-1)  perror……


left = MAXDATA;
recvbyte = 0;
while (left > 0) {
n = recv(sockfd, buff+recvbyte, left, 0);

....
left -= n;
recvbyte += n;
}
可以参考unix 网络编程上 readn的做法,  另外,最好有个简单协议
------解决方案--------------------
LS有好几位提出了组包,判断合法的包就解析出来。这个主意不错。有个简单的协议比较合适。
------解决方案--------------------

m = num;
ptr = buff;
while (m > 0)
{
    n = send(clientfd, ptr, m, 0);
    if (n == -1) ...
    ptr += n;
    m -= n;
    printf("n:%d\n", n);