最简单的网路编程折射出的一些问题

下面的代码是一个简单的C/S程序,程序源于《UNIX网络编程》第五章,程序实现如下功能:
在客户端的标准输入上输入一个字符串,到达服务端之后,服务端原样返回字符串给客户端,在客户端回显该字符串。

首先是客户端和服务端的代码描述:

server.c代码:
int main()
{
 int listenfd;
 int connfd;
 pid_t child_pid;
 size_t len;
 struct sockaddr_in clientaddr = {0};
 struct sockaddr_in serveraddr = {0};

 listenfd = socket( AF_INET, SOCK_STREAM, 0);

 serveraddr.sin_family = AF_INET;
 serveraddr.sin_addr.S_addr = htonl(INADDR_ANY);
 serveraddr.sin_port = htons(9999);

 bind(listenfd,(struct sockaddr*)&serveraddr, sizeof(serveraddr));

 listen(listenfd, 5);

 while (1)
 {
  len = sizeof(clientaddr);
  connfd = accept(listenfd,(struct sockaddr*)&clientaddr, &len);

  if ( (child_pid = fork()) == 0)
  {
   close(listenfd);
   str_echo(connfd);
   exit(0);
  }
  close(connfd);
 }
}

void str_echo( int sockfd )
{
 size_t n ;
 char buf[1024] = {0};

again:
 while ( (n = read(sockfd, buf,1024)) > 0 )
 {
  write(sockfd, buf, n );
 }

 if ( n < 0 && errno == EINTR )
 {
  goto again:
 }
 else if(n < 0)
 {
  err_sys("read err!");
 }
}

client.c的代码


int main()
{
 int sockfd;
 struct sockaddr_in serveraddr = {0};

 sockfd = socket( AF_INET, SOCK_STREAM, 0);

 serveraddr.sin_family = AF_INET;
 serveraddr.sin_addr.S_addr = htonl(INADDR_ANY);
 serveraddr.sin_port = htons(9999);

 connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));

 str_cli(stdin,sockfd);

 exit(0);
}

void str_cli( FILE* fp, int sockfd )
{
 char sendline[1024] = {0};
 char recvline[1024] = {0};

 while( NULL != fgets(sendline, 1024, fp))
 {
  write(sockfd, sendline, strlen(sendline));

  if ( 0 == read(sockfd, recvline, 1024))
  {
   err_quit("str_cli:sever terminated prematurely");
  }

  fputs(recvline,stdout);
 }
}

程序非常的简单,但是程序折射出来的问题需要我们细细的去琢磨,有如下的问题需要去思考:
(1) 客户端和服务端的建链过程是什么?需要了解三次握手建链,及建链过程中的状态转移
(2) 客户端和服务端分别正常终止的时候,程序会发生什么样的情况?
(3) 客户端和服务端分别异常终止的时候,程序会发生什么样的情况?

程序最后的总结:
(1) 如何处理僵尸子进程;---捕获SIGCHILD信号
(2) 当服务器进程终止的时候,客户端进程没有感知到,这需要怎样处理?---IO复用
(3) 服务器主机崩溃,需要客户端向服务端发送了数据才能检测到?---SO_KEEPALIVE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值