免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: sjh_311
打印 上一主题 下一主题

[C] [请教]TCP长连接socket问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-11-07 10:09 |只看该作者
原帖由 baohuaihuai 于 2007-11-7 09:46 发表


如果send端只send了8个字节然后又不关闭连接,而recv端是按1K接收的,那recv就会一直阻塞在那里,直到数据满1K或者发送端关闭连接.(阻塞方式)

不是这样的,TCP发送的报文段的大小是根据路径MTU得出的。

论坛徽章:
0
12 [报告]
发表于 2007-11-07 10:22 |只看该作者
接收端的测试代码:
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int sock_lsn, sock_new;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct sockaddr_in server, client;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t sin_size=sizeof(struct sockaddr_in);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char buf[2000];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t len;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bzero(&server,sizeof(server));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server.sin_family = AF_INET;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server.sin_port =htons(50789);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server.sin_addr.s_addr =inet_addr("192.168.0.2");

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((sock_lsn = socket(AF_INET,SOCK_STREAM,0))<0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("socket");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(bind(sock_lsn,(struct sockaddr *)&server,sizeof(struct sockaddr))<0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("bind");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen(sock_lsn,5);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((sock_new=accept(sock_lsn,(struct sockaddr *)&client,&sin_size))<0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("socket");
&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;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(1){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len=recv(sock_new,buf,2000, 0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(len >0){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s\n", buf);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sock_new);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sock_lsn);
}

发送端的测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include<unistd.h>
#include <sys/select.h>
#include <sys/time.h>

#define CORE_PORT       50789

main(int argc ,char **argv)
{
&nbsp;int s,n;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char buf[]="11111111111111111111111111111111111111111111111111111111111111111111111\
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char buf1[]="222222222222222222222222222222222222222222222222222222222222222222222222\
222222222222222222222222222222222222222222222222222222222222222222222222"
;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char buf2[]="333333333333333333333333333333333333333333333333333333333333333333333333\
333333333333333333333333333333333333333333333333333333333333333333333333"
;

&nbsp;struct sockaddr_in servaddr;
&nbsp;s=socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(CORE_PORT);
servaddr.sin_addr.s_addr=inet_addr("192.168.0.2");
if((n=connect(s,(struct sockaddr *)&servaddr,sizeof(servaddr)))==-1)
printf("connect error!");
int len =0;
int cnt = 0;
struct timeval waittm;
waittm.tv_sec = 0;
waittm.tv_usec = 20000;
printf("start\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;int readlen=sizeof(buf);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len= write(s,buf,readlen);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("len = %d\n", len);
printf("send 1:\n%s\n", buf);
select(0, NULL,NULL,NULL, &waittm);
&nbsp;&nbsp;&nbsp;&nbsp;readlen=sizeof(buf1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len = write(s,buf1,readlen);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("len = %d\n", len);
printf("send 2:\n%s\n", buf1);
select(0, NULL,NULL,NULL, &waittm);

&nbsp;&nbsp;&nbsp;&nbsp;readlen=sizeof(buf2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len = write(s,buf2,readlen);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("len = %d\n", len);
printf("send 2:\n%s\n", buf2);
select(0, NULL,NULL,NULL, &waittm);
printf("round %d\n", cnt);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnt ++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(cnt == 40)break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
printf("cnt = %d\n", cnt);
sleep(1000);
}

客户端发每隔一会儿发一个,一共40次,120个包。
服务端只能收到一半的包?

[ 本帖最后由 sjh_311 于 2007-11-7 13:02 编辑 ]

论坛徽章:
0
13 [报告]
发表于 2007-11-07 10:29 |只看该作者
发送端程序结束的时候没调用close将描述符关闭。

论坛徽章:
0
14 [报告]
发表于 2007-11-07 10:30 |只看该作者
可能buffer中剩余的内容被丢弃了吧?

论坛徽章:
0
15 [报告]
发表于 2007-11-07 12:47 |只看该作者
原帖由 cugb_cat 于 2007-11-7 10:29 发表
发送端程序结束的时候没调用close将描述符关闭。

呃,是没关。但不影响发包。
服务器端抓包显示是收了120个包,可是实际recv到的只有一半左右……

论坛徽章:
0
16 [报告]
发表于 2007-11-07 12:53 |只看该作者
原帖由 sjh_311 于 2007-11-7 12:47 发表

呃,是没关。但不影响发包。
服务器端抓包显示是收了120个包,可是实际recv到的只有一半左右……

对了,你在recv那儿添加错误处理的语句试试,就是recv返回-1的时候。
还有,客户端和服务端使用的端口不一致,这是怎么回事呢?

[ 本帖最后由 cugb_cat 于 2007-11-7 12:55 编辑 ]

论坛徽章:
0
17 [报告]
发表于 2007-11-07 13:08 |只看该作者
recv返回-1表示对方关闭socket,这个和接收没有关系吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP