UNIX网络编程卷1(第三版) 客户/服务器程序示例

举报
心跳包 发表于 2021/11/12 23:33:28 2021/11/12
【摘要】 1.TCP回射服务器程序:main函数 #include "unp.h" intmain(int argc, char **argv){ int listenfd, connfd; pid_t childpid; socklen_t clilen; struct sockaddr_in cliaddr, servad...

1.TCP回射服务器程序:main函数


  
  1. #include "unp.h"
  2. int
  3. main(int argc, char **argv)
  4. {
  5. int listenfd, connfd;
  6. pid_t childpid;
  7. socklen_t clilen;
  8. struct sockaddr_in cliaddr, servaddr;
  9. void sig_chld(int);
  10. listenfd = Socket(AF_INET, SOCK_STREAM, 0);
  11. bzero(&servaddr, sizeof(servaddr));
  12. servaddr.sin_family = AF_INET;
  13. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  14. servaddr.sin_port = htons(SERV_PORT);
  15. Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
  16. Listen(listenfd, LISTENQ);
  17. Signal(SIGCHLD, sig_chld);
  18. for ( ; ; ) {
  19. clilen = sizeof(cliaddr);
  20. if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
  21. if (errno == EINTR)
  22. continue; /* back to for() */
  23. else
  24. err_sys("accept error");
  25. }
  26. if ( (childpid = Fork()) == 0) { /* child process */
  27. Close(listenfd); /* close listening socket */
  28. str_echo(connfd); /* process the request */
  29. exit(0);
  30. }
  31. Close(connfd); /* parent closes connected socket */
  32. }
  33. }

创建TCP套接字。在待绑定到该套接字的网际网套接字地址结构中填入通配地址(INADDR_ANY)和服务器众所周知的端口(SERV_PORT).捆绑通配地址是告诉系统:要是系统是多宿主机,我们将接受目的地址为任何本地接口的连接。listen把该套接字转成一个监听套接字。

服务器阻塞于accept调用,等待客户端连接完成。

fork为每个客户派生给一个处理它们的子进程。子进程关闭监听套接字,父进程关闭已连接的套接字。。子进程调用str_echo处理客户。


  
  1. #include "unp.h"
  2. void
  3. str_echo(int sockfd)
  4. {
  5. ssize_t n;
  6. char buf[MAXLINE];
  7. again:
  8. while((n=read(sockfd,buf,MAXLINE))>0)
  9. Writen(sockfd,buf,n);
  10. if(n<0&&errno==EINTR)
  11. goto again;
  12. else if(n<0)
  13. errr_sys("str_echo:read error");
  14. }

read函数从套接字读入数据,writen函数把其内容回射给客户。如果客户关闭连接,那么接收到客户的FIN将导致服务器子进程的read函数返回0,这又导致str_echo函数的返回,从而终止子进程。

2.TCP回射客户程序:main函数


  
  1. /* Use standard echo server; baseline measurements for nonblocking version */
  2. #include "unp.h"
  3. int
  4. main(int argc, char **argv)
  5. {
  6. int sockfd;
  7. struct sockaddr_in servaddr;
  8. if (argc != 2)
  9. err_quit("usage: tcpcli <IPaddress>");
  10. sockfd = Socket(AF_INET, SOCK_STREAM, 0);
  11. bzero(&servaddr, sizeof(servaddr));
  12. servaddr.sin_family = AF_INET;
  13. servaddr.sin_port = htons(7);
  14. Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
  15. Connect_timeo(sockfd, (SA *) &servaddr, sizeof(servaddr), 10);
  16. str_cli(stdin, sockfd); /* do it all */
  17. exit(0);
  18. }

3.POSIX信号处理

信号就是告知某个进程发生了某个事件的通知,有时候也称为软件中断,信号通常是异步的,也就是进程预先不知道信号的准确发生时刻。

信号可以:由一个进程发给另一个进程或者自身;由内核发给某个进程。

每个信号都有一个与之关联的处置,也称为行为。

 

 

文章来源: xintiaobao.blog.csdn.net,作者:心跳包,版权归原作者所有,如需转载,请联系作者。

原文链接:xintiaobao.blog.csdn.net/article/details/106094089

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。