免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7957 | 回复: 9
打印 上一主题 下一主题

send 出错问题 connection reset by peer [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-24 01:31 |只看该作者 |倒序浏览
问个问题,我在Linux里面写了个服务器小程序,用来发送大文件,在windows写了个客户端小程序,用来接受服务器发来的文件,当我的文件超过100K左右的时候Linux里面的服务器程序里面的send语句就会返回-1,出现“connection reset by peer”这样的错误.同样的算法把window作为服务器,Linux作为客户端就没有这样的错误。当文件大小为10来K 左右的时候就不会出现错误。我个人觉得是不是因为缓冲区溢出了?各位有什么见解,为什么呢?

代码:
int Recv(int sock,char *buf)
{
        int len=0,result =0;
        if(-1== recv(sock,(char *)&len,sizeof(int),0))
        {
                perror("error : ");
        }
       
        result = recv(sock,buf,len,0);
       
        if(result == -1)
        {
                perror("error : ");
        }
        if(result != len)
        {
                printf("recive error\n");
                exit(0);
        }
        return len;
}

int Send(int sock,char *buf,int len)
{
        int net_len=len;
        if(-1==send(sock,(char *)&net_len,sizeof(int),0))
        {
                perror("error : ");
                return -1;
        }
        if(-1==send(sock,buf,len,0))
        {
                perror("error : ");
                return -1;
        }
}



void RecvFile(int sock,char *filename)
{
    FILE *fp;
    char *buffer = (char *)malloc(BUFFERSIZE + sizeof(int));
    int len=0;
    printf("download file : %s\n",filename);
    fp = fopen(filename ,"wb");
    do

    {       

        len=Recv(sock,buffer);
        if(len!=BUFFERSIZE)
        {
                len = *((int *)(buffer+BUFFERSIZE));
        }

        fwrite(buffer,1,len,fp);

    }while(len==BUFFERSIZE);

    fclose(fp);
}


void SendFile(int sock,char *filename)

{

        FILE *fp;
        int len=0;

        char *buffer = (char *)malloc(BUFFERSIZE+sizeof(int));
        printf("sending file %s \n",filename);
       
       fp = fopen(filename ,"rb");
       do
             
       {

                len=fread(buffer,1,BUFFERSIZE,fp);
               
                if(len <BUFFERSIZE)

                {

                        *((int *)(buffer+BUFFERSIZE))=len;
                       
                        len=BUFFERSIZE+sizeof(int);

                }

                Send(sock,buffer,len);

        }while(len==BUFFERSIZE);

        fclose(fp);

}

论坛徽章:
0
2 [报告]
发表于 2009-08-24 13:11 |只看该作者
1. 你有没有检查此时你的接收端是什么状态?网络应用中要两端都看。
2. 有没有抓包看双方的交互?

从你代码看,你假设了recv一次肯定收满指定的长度,但你用的是TCP,这种流式协议有可能在任何地方分开,所以有可能是你的收端退出了,然后导致发端继续发数据过程中产生一个RST。

recv有一个WATI_ALL的选项参数,但只有部分系统支持,所以要想达到这种效果需要你自己去设计。UNIX Network Programming中应该有类似的封装。

论坛徽章:
0
3 [报告]
发表于 2009-08-25 13:07 |只看该作者

回复 #2 Cyberman.Wu 的帖子

没有分开,我的那个程序只用了我那两个封装好的发送和接受函数。
还有你说的抓包我没试过,也不知道怎么搞。可能是基础太差了。需要继续修炼。

论坛徽章:
0
4 [报告]
发表于 2009-08-25 13:44 |只看该作者

回复 #3 Lensan_go 的帖子

这个应该是这里导致接收端退出,从而使发送端后续的发送导致RST:
        if(result != len)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("recive error\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

论坛徽章:
0
5 [报告]
发表于 2009-08-25 16:38 |只看该作者

回复 #4 Cyberman.Wu 的帖子

可能是这里出错,但是,为什么会这样呢?我调过来让windows 来发,linux来收就不会出问题。

论坛徽章:
0
6 [报告]
发表于 2009-08-25 20:58 |只看该作者

回复 #5 Lensan_go 的帖子

那只是各系统的实现上略有不同,如果你中间隔个互联网,不管怎么跑都会出问题。以前我们的系统中有一个基于TCP的分布式应用,当时的同事就是不知道这一点儿,但那个原来在Windows上模拟测试时测了很久一直没出问题,但上板之后在VxWorks中不停地出问题。

论坛徽章:
0
7 [报告]
发表于 2009-08-26 08:57 |只看该作者

回复 #4 Cyberman.Wu 的帖子

说的对。
这段代码出错时应该的,不出错就不应该了。除非单步调试,或者有延时之类。
tcp分包一般都是1460.
你一包100k数据过去应该连续循环收100k/1460次才能收完。
你这一次就exit,socket就结束了
tcp当然会向对方发一个rst报文。

论坛徽章:
0
8 [报告]
发表于 2009-08-26 21:16 |只看该作者
同意楼上的,你发送的报文超过MTU大小了,为了移植性和兼容性,报文大小最好<=MTU

论坛徽章:
0
9 [报告]
发表于 2009-08-27 13:45 |只看该作者

回复 #8 rollin7 的帖子

TCP不存在报分包的概念,不要去猜协议栈如何分IP包;就算你控制了发端也控制不了收端如何去返回给用户层。老老实实按流式协议对待它。

论坛徽章:
0
10 [报告]
发表于 2009-08-27 21:53 |只看该作者
感谢各位指导,虽然还不是很理解,不过,我也大概知道为什么出错了。谢谢。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP