当前位置:  技术问答>linux和unix

采用fork(),客户端为什么会接收到重复的字符串呢?

    来源: 互联网  发布时间:2017-01-15

    本文导语:  服务器功能是向每一个客户端发送字符串,然后关闭与客户端的连接。当客户端连接个数超过5个后,就退出服务器程序。 客户端功能:连接上服务器,读取接收到的字符串并显示,然后关闭连接并退出程序。 server.c...

服务器功能是向每一个客户端发送字符串,然后关闭与客户端的连接。当客户端连接个数超过5个后,就退出服务器程序。
客户端功能:连接上服务器,读取接收到的字符串并显示,然后关闭连接并退出程序。

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理解不深,看书先.

|
用_exit()试试?

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 字符方式下汉化RH7.1 采用unicon-3.0.3-release.tar.gz(2.4.5 patch)包,怎么会这样?!help!!!........
  • 采用Linux/Unix作为服务器和采用windows系列有什么优缺点呢?
  • 作CRM现在使用什么开发工具比较方便?采用什么结构?
  • 采用Flash的嵌入式系统中是否难以应用数据库?
  • 请教有没有谁在 LINUX下实现对DVD光盘采用UDF格式刻录的?
  • 如果CSDN采用JSP技术,访问速度会不会加快
  • 请问应用服务器本身也是采用多层结构吗?疑惑中。
  • Solaris系统下,使用gcc编译程序,请问采用1字节对齐应该怎样设置
  • 在调用pthread_testcancel时要采用这样的方式???
  • YC2440开发板采用什么串口线?
  • 消息队列一般是怎么使用的,是采用While的方式进行轮询么
  • 采用UDP对ARM系统远程监测
  • 一个可以自动排序、频繁增删的队列,采用哪种数据结构比较好?
  • 关于采用NT Loader引导redhat7.2的问题。
  • linux系统下,采用 ADSL 路由方式上网,如何设置网络端口interface的值?
  • 各位高手:servlet如何接收采用http上传(如同Email的附件)的文件?
  • linux 可以采用crypt来加密口令,不知道有什么解密方法没有?
  • 采用XML时候大家用DTD还是SCHEMA。
  • HP-UX 11.0 采用的是unix操作系统吗?
  • 怎么样去除浏览器中的滚动条,而采用内部的滚动条!
  • Primitive 与 String 之间的转换必须采用封装类吗?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3