linux下socket连接返回报文丢失问题

angel518 2016-11-17 04:11:53
在网上学习别人socket并发模式一个程序,并进行修改了测试,服务端如下
static void *handle_request(void *argv){
int newfd = *((int *)argv);
char buf[BUFLEN];
int len;
time_t now;
/******处理客户端请求*******/
printf("begin a pthread\n");
bzero(buf,BUFLEN);
len = recv(newfd,buf,BUFLEN,0);
if(len >0 && !strncmp(buf,"TIME",4)){
bzero(buf,BUFLEN);
/*获取系统当前时间*/
now = time(NULL);
/*ctime将系统时间转换为字符串,sprintf使转化后的字符串保存在buf*/
sprintf(buf,"newfd=%d,%24s\r\n",newfd,ctime(&now));
//******发送系统时间*******/
send(newfd,buf,strlen(buf),0);
}
close(newfd);
printf("end a pthread\n");
return NULL;
}

static void handle_connect(int sockfd){
int newfd;
struct sockaddr_in c_addr;
socklen_t len;
pthread_t thread_s;

while(1){
len = sizeof(struct sockaddr);
if((newfd = accept(sockfd,(struct sockaddr*) &c_addr, &len)) >0){
printf("\n*****************通信开始***************\n");
printf("正在与您通信的客户端是:%s: %d newfd=%d\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port),newfd);
/*创建线程来处理连接*/
sleep(5); //**//为什么这里加sleep后 同时多个客户端连接第一个会死在那里
pthread_create(&thread_s,NULL,handle_request,(void *)&newfd);
}
}
}

int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in s_addr;
unsigned int port, listnum;
if(argc<3){
(void *)fprintf(stdout,"参数错,命令格式:命令 ip地址 端口 侦听队列长度");
exit(-1);
}
/*建立socket*/
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket");
exit(errno);
}else
printf("socket create success!\n");
if(argv[2])
port = atoi(argv[2]);
else
port = 4567;
if(argv[3])
listnum = atoi(argv[3]);
else
listnum = 3;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(port);
if(argv[1])
s_addr.sin_addr.s_addr = inet_addr(argv[1]);
else
s_addr.sin_addr.s_addr = INADDR_ANY;
if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1){
perror("bind");
exit(errno);
}else
printf("bind success!\n");
if(listen(sockfd,listnum) == -1){
perror("listen");
exit(errno);
}else
printf("the server is listening!\n");
handle_connect(sockfd);
close(sockfd);
return 0;
}

客户端如下:
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in s_addr;
socklen_t len;
unsigned int port;
char buf[BUFLEN];
pid_t pid;
int num=atoi(argv[3]);

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket");
exit(errno);
}else
printf("Socket create success!\n");

if(argv[2])
port = atoi(argv[2]);
else
port = 4567;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(port);
if (inet_aton(argv[1], (struct in_addr *)&s_addr.sin_addr.s_addr) == 0) {
perror(argv[1]);
exit(errno);
}
if(connect(sockfd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr)) == -1){
perror("connect");
exit(errno);
}else
printf("Conncet success!\n");
bzero(buf,BUFLEN);
strcpy(buf,"TIME");
send(sockfd,buf,strlen(buf),0);
bzero(buf,BUFLEN);
len = recv(sockfd,buf,BUFLEN,0);
printf("buf=[%s]len=[%d]\n",buf,len);
if(len > 0) //**//中断服务端时最先连服务端的客户端会返回len=-1,居然会执行下列打印
printf("The server return time is:%s\n",buf);
close(sockfd);
return 0;
}

问题如下:启动服务端后,再同时(在5秒内)启动两个或以上客户端连接,按理应该是第一个客户端连到服务端后打印Socket create success!Conncet success!后,休眠5秒创建第一个客户端连接的线程并返回服务器时间,然后第二个客户端连接上去并休眠5秒再打印服务端返回的时间;但实际上是第一个客户端连接成功后只打印Socket create success!Conncet success!,屏幕既不断开也无服务端返回的报文输出,倒是后面连接的客户端能完整打印服务端返回的时间
而且等了很久第一个客户端还是那样,就中断掉服务端,这时第一个客户端才返回
buf=[]len=[-1]
The server return time is
这样的信息,而且既然len=-1了,必然小于0,怎么会把 if(len > 0) printf("The server return time is:%s\n",buf);这句执行了

...全文
503 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-11-19
  • 打赏
  • 举报
回复
看链接指向的帖子。
angel518 2016-11-18
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
建议楼主先学会使用抓包软件比如wireshark
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
你在说禅啊,我咋听不懂
赵4老师 2016-11-18
  • 打赏
  • 举报
回复
建议楼主先学会使用抓包软件比如wireshark
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
angel518 2016-11-17
  • 打赏
  • 举报
回复
引用 1 楼 sunyongliang118 的回复:
单步调试。或者你贴全代码,别人给你调试。
这就是全码,最多没包含引入的库文件
振翅高飞 2016-11-17
  • 打赏
  • 举报
回复
单步调试。或者你贴全代码,别人给你调试。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧