UNIX网络编程学习(三)——套接字编程---服务端

5 篇文章 0 订阅
5 篇文章 0 订阅

我总觉得总结是件很痛苦的事情,我想一直推进向前学习。但不做总结又感觉少了点什么。

下图是来自书中的TCP服务器端的实例

  #include "unp.h"
  
>>int main(int argc, char **argv)
  {
      int listenfd, connfd;
      pid_t childpid;
      socklen_t clilen;
      struct sockaddr_in cliaddr, servaddr;
      listenfd = Socket(AF_INET, SOCK_STREAM, 0);
      bzero(&servaddr, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
      servaddr.sin_port = htons(SERV_PORT);
      Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
      Listen(listenfd, LISTENQ);
      for(; ;) {
          clilen = sizeof(cliaddr);
          connfd = Accept(listenfd, (SA *)&cliaddr, &clilen);
          if((childpid = Fork() == 0)){
              Close(listenfd);
              str_echo(connfd);
              exit(0);
          }
          Close(connfd);
      }
  }

  TCP服务端的建立要先经历socket--->bind--->listen三个阶段,然后阻塞在accpet阶段,等待客户端发起服务请求。当收到来自客户端的请求以后,客户端和服务端还要经历三次握手以完成连接的建立,然后才能进行正常的通信。

     根据代码一行一行来看这个过程。

     首先是socket创建套接字。socket函数原型为——socket(family, int type, int protocol)。参数依次为协议族(IPV4 OR IPV6)、套接字类型(字节流、数据报......)和传输端协议类型(IPPROTO_TCP, IPPROTO_UDP,IPPROTO_SCTP)。socket成功时将返回一个套接字描述符,它与文件描述符类似。其实我有种明悟,unix系统中,万物皆文件,因此无论是记录信息亦或是传输信息都要一个fd来标识。扯远了,继续总结。

     然后是bind绑定套接字描述符到本地的一个进程上。绑定的套接字对象要设置好地址和端口以供客户端访问。这里可能会混淆的是“端口”这一概念。我以前经常会以为这个端口就是进程的pid,其实不是。pid是本地用以标识该进程的描述符,而ip:port组合在一起可以让客户端标识该服务器。

    接着服务器开始监听,listen。listen第一个参数即是套接字描述符,第二个参数是最大连接数。最大连接数由已建立连接数+未建立连接数组成。已建立连接就是和服务器完成三次握手的客户连接。

   当和客户连接建立好之后,服务器就可以调用accpet拿到客户端的地址clienaddr和地址大小clilen。同时accept会返回和客户端建立起连接的套接字描述符。这个套接字描述符有别于前面socket创建的;由accpet返回的称之为连接套接字,而由socket创建的则可称为监听套接字。代码中在accpet之后,fork了一个子进程来和客户端进行数据上的交互(str_echo),而父进程则关闭这个连接套接字继续监听(close(connfd))。子进程为什么要Close(listenfd),而父进程为什么要Close(connfd)呢?这是为了保证最后连接能顺利关闭。

     unix系统中在删除文件时,要等到该文件的引用计数为0时才进行删除操作。代码中的一次Close操作就是一次引用减1。如果没有这个操作,很容易发现,当最后关闭连接时,某个套接字描述符引用计数不为0,删除不了。DAMN IT !!!!!

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值