当前位置: 技术问答>linux和unix
采用fork(),客户端为什么会接收到重复的字符串呢?
来源: 互联网 发布时间:2017-01-15
本文导语: 服务器功能是向每一个客户端发送字符串,然后关闭与客户端的连接。当客户端连接个数超过5个后,就退出服务器程序。 客户端功能:连接上服务器,读取接收到的字符串并显示,然后关闭连接并退出程序。 server.c...
服务器功能是向每一个客户端发送字符串,然后关闭与客户端的连接。当客户端连接个数超过5个后,就退出服务器程序。
客户端功能:连接上服务器,读取接收到的字符串并显示,然后关闭连接并退出程序。
server.c:
client.c
下面是一个测试用的脚本(a.sh): 连续运行8个客户端程序
测试方法一:取消对server.c中64行的注释,a.sh运行结果为:
[zcm@t #151]$./a.sh
Received: Hello world1
1
Received: Hello world2
2
Received: Hello world3
3
Received: Hello world4
4
Received: Hello world5
5
Received: Hello world6
6
connect: Connection refused
7
connect: Connection refused
8
测试方法二:注释掉server.c中第64行代码,a.sh的运行结果为:
[zcm@t #152]$./a.sh
Received: Hello world1
1
Received: Hello world2
2
Received: Hello world3
3
Received: Hello world2
4
Received: Hello world3
5
Received: Hello world4
6
Received: Hello world4
7
Received: Hello world3
8
可见,把server.c中第64行注释后,接收到的字符串有重复的现象,到底应该怎么解释呢,想不明白,请高人解答!
客户端功能:连接上服务器,读取接收到的字符串并显示,然后关闭连接并退出程序。
server.c:
1 // 服务器端:向每个客户端发送字符串“Hello world%d”,然后关闭socket。当客户端个数大于5个时,就退出服务器。
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #define MYPORT 4000
11 #define BACKLOG 10
12 int main(int argc, char *argv[])
13 {
14 int sock_fd, new_fd;
15 struct sockaddr_in my_addr;
16 struct sockaddr_in their_addr;
17 int sin_size;
18 if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
19 {
20 perror("socket");
21 return 1;
22 }
23 my_addr.sin_family = AF_INET;
24 my_addr.sin_port = htons(MYPORT);
25 my_addr.sin_addr.s_addr = INADDR_ANY;
26 bzero(&(my_addr.sin_zero), 8);
27 if(bind(sock_fd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1)
28 {
29 perror("bind");
30 return 1;
31 }
32 if(listen(sock_fd, BACKLOG) == -1)
33 {
34 perror("listen");
35 return 1;
36 }
37 int count = 0;
38 while(1)
39 {
40 sin_size = sizeof(struct sockaddr_in);
41 if((new_fd = accept(sock_fd, (struct sockaddr*)&their_addr, &sin_size)) == -1)
42 {
43 perror("accept");
44 continue;
45 }
46 printf("server: got connection from [%s]n", inet_ntoa(their_addr.sin_addr));
47 char str[100] = {0};
48 sprintf(str, "Hello world%d", ++count);
49 if(!fork()) // child process
50 {
51 if(send(new_fd, str, sizeof(str), 0) == -1)
52 {
53 perror("send");
54 close(new_fd);
55 return 0;
56 }
57 close(new_fd);
58 printf("Close connection with client-[%s]nn", inet_ntoa(their_addr.sin_addr));
59 exit(0); // 注释掉此句的话,客户端收到的字符串就有可能重复
60 }
61 else // parent process
62 {
63 if(count > 5)
64 break;
65 }
66 }
67 while(waitpid(-1, NULL, WNOHANG) > 0);
68 close(sock_fd);
69 return 0;
70 }
client.c
// 客户端:connect到服务端,读取接收到的字符串并显示,然后退出程序。
#include
#include
#include
#include
#include
#include
#include
#include
#define MYPORT 4000
#define MAXDATASIZE 100
int main(int argc, char *argv[])
{
int sock_fd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
if(argc != 2)
{
fprintf(stderr, "Usage: %s n", argv[0]);
return 0;
}
if((he = gethostbyname(argv[1])) == NULL)
{
herror("gethostbyname");
return 1;
}
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
return 1;
}
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(MYPORT);
their_addr.sin_addr = *((struct in_addr*)he->h_addr);
bzero(&(their_addr.sin_zero), 8);
if(connect(sock_fd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect");
return 1;
}
if((numbytes = recv(sock_fd, buf, MAXDATASIZE, 0)) == -1)
{
perror("recv");
return 1;
}
buf[numbytes] = 0;
printf("Received: %sn", buf);
close(sock_fd);
return 0;
}
下面是一个测试用的脚本(a.sh): 连续运行8个客户端程序
#!/bin/bash
i=0
while [ $i -lt 8 ];
do
./myclient Fedora12_TIANXIAOKU
i=$((i+1))
echo $i
done
测试方法一:取消对server.c中64行的注释,a.sh运行结果为:
[zcm@t #151]$./a.sh
Received: Hello world1
1
Received: Hello world2
2
Received: Hello world3
3
Received: Hello world4
4
Received: Hello world5
5
Received: Hello world6
6
connect: Connection refused
7
connect: Connection refused
8
测试方法二:注释掉server.c中第64行代码,a.sh的运行结果为:
[zcm@t #152]$./a.sh
Received: Hello world1
1
Received: Hello world2
2
Received: Hello world3
3
Received: Hello world2
4
Received: Hello world3
5
Received: Hello world4
6
Received: Hello world4
7
Received: Hello world3
8
可见,把server.c中第64行注释后,接收到的字符串有重复的现象,到底应该怎么解释呢,想不明白,请高人解答!
|
子进程不exit岂不是又跑到accept的地方了? 那代码逻辑不就乱了 ?
楼主对fork理解不深,看书先.
楼主对fork理解不深,看书先.
|
用_exit()试试?