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

2023-05-16

今天在写简单的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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐