论坛首页 综合技术论坛

解决Linux 下server和client 通过TCP通讯:accept成功接收却报错的问题

浏览 4617 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2020-12-30  
 今天在写简单的TCP通讯例子的时候,遇到了一个问题:server 和client能够连接成功,并且client也能够正常发送,但server就是接收不到,在网上搜索一番后,终于解决了问题。在这里整理如下:

  大家要注意的是,一个server端可以连接多个client端,server端的accept()函数负责等待并接收client的连接请求,而且accept()函数将不同client端的sockfd作为返回值。为了保证接收到对应的client端数据,所以在client连接成功且使用recv()函数接收数据的时候,recv()函数的第一个参数应该是accept成功后的返回值。

实例代码如下:

1.server端


1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <unistd.h>
8 #include <netinet/in.h>
9 #include <netdb.h>
10
11 #define MAX_MSG_LEN 1024
12 #define BACKLOG     10
13
14 int main(int argc,char *arg[])
15 {
16     struct sockaddr_in servAddr,clidAddr;
17     struct hostent *host = NULL;
18     int Port = 0,socketFd,sin_size;
19     socklen_t peerlen;
20     int recLen = 0;
21     char buf[MAX_MSG_LEN] = {0};
22    
23     if(argc<2)
24     {
25         printf("please input port number!\r\n");
26         return -1;
27     }
28
29     //                     ipV4        TCP     0
30     if((socketFd=socket(AF_INET,SOCK_STREAM,0))==-1)
31     {
32         perror("socket");
33         return -1;
34     }   
35     printf("socket fd = %d\n",socketFd);
36    
37    
38     memset(&servAddr,0,sizeof(struct sockaddr_in));
39     servAddr.sin_family = AF_INET;
40     servAddr.sin_port   = htons(atoi(arg[1]));
41     servAddr.sin_addr.s_addr= INADDR_ANY;
42    
43     if(bind(socketFd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr))==-1)
44     {
45         perror("bind:");
46     }
47     else
48     {
49         printf("bind success \r\n");
50     }
51    
52     if(listen(socketFd,BACKLOG)==-1)
53     {
54         perror("listen:");
55     }
56     else
57     {
58         printf("Listening...\r\n");
59     }
60     sin_size=sizeof(struct sockaddr_in);
61    
62     if((socketFd=accept(socketFd,(struct sockaddr *)&clidAddr,&sin_size))==-1)
63     {
64             perror("accept:");
65             return -1;
66     }
67         else
68     {
69             printf("accept successful!\r\n");
70     }
71    
72     while(1)
73     {
74         memset(buf,0,sizeof(buf));
75         if((recLen = recv(socketFd,buf,MAX_MSG_LEN,0))==-1)
76         {
77             perror("recv:");
78         }
79         else
80         {
81             if(recLen>0)
82             {
83                 recLen = 0;
84                 printf("Receive a message:%s\r\n",buf);
85             }
86         }
87     }   
88     close(socketFd);
89     return 0;
90 }

上述代码的关键在于62行:

if((socketFd=accept(socketFd,(struct sockaddr *)&clidAddr,&sin_size))==-1)
recv(socketFd,buf,MAX_MSG_LEN,0);
将sockfd赋值为accept的返回值问题就解决了,为了实验方便,这里一并附上client代码:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>

#define MAX_MSG_LEN 1024

int main(int argc,char *arg[])
{
    struct sockaddr_in servAddr;
    struct hostent *host = NULL;
    int Port = 0,socketFd;
    char buf[MAX_MSG_LEN] = {0};
   
    if(argc<3)
    {
        printf("please input IP and port number!\r\n");
        return -1;
    }
   
    if((host = gethostbyname(arg[1]))==NULL)
    {
        return -1;
    }   
    //                     ipV4        TCP     0
    if((socketFd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("socket");
        return -1;
    }   
    printf("socket fd = %d\n",socketFd);
    memset(&servAddr,0,sizeof(struct sockaddr_in));
    servAddr.sin_family = AF_INET;
    servAddr.sin_port   = htons(atoi(arg[2]));
    servAddr.sin_addr    = (*(struct in_addr *)host->h_addr);
   
    if(connect(socketFd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr))==-1)
    {
        perror("connect:");
        return -1;
    }
   
    while(1)
    {
        printf("input:");
        scanf("%s",buf);
        if(send(socketFd,buf,sizeof(buf),0)==-1)
        {
            perror("send:");
        }
        {
            printf("send successful!\r\n");
        }
        memset(buf,0,sizeof(buf));
    }
    close(socketFd);
    return 0;
}
Linux的一些学习资料欢迎自己观看哈

九天学会linuxC语言

http://www.makeru.com.cn/course/1861.html?s=45051

Linux网络经典案例

http://www.makeru.com.cn/live/3485_1630.html?s=45051

Linux网络高并发技术之epoll

http://www.makeru.com.cn/live/5413_1937.html?s=45051

linux之C语言内存管理

http://www.makeru.com.cn/live/1392_382.html?s=45051

Linux网络聊天室设计

http://www.makeru.com.cn/live/1392_1099.html?s=45051

可以来一些学习交流群:943552345

论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics