×

Socket网络高级编程

消耗积分:1 | 格式:rar | 大小:0.5 MB | 2017-10-18

分享资料个

  10.3 网络高级编程
  在实际情况中,人们往往遇到多个客户端连接服务器端的情况。由于之前介绍的如connet()、recv()和send()等都是阻塞性函数,如果资源没有准备好,则调用该函数的进程将进入睡眠状态,这样就无法处理I/O多路复用的情况了。本节给出了两种解决I/O多路复用的解决方法,这两个函数都是之前学过的fcntl()和select()(请读者先复习第6章中的相关内容)。可以看到,由于在Linux中把socket也作为一种特殊文件描述符,这给用户的处理带来了很大的方便。
  1.fcntl()
  函数fcntl()针对socket编程提供了如下的编程特性。
  n 非阻塞I/O:可将cmd设置为F_SETFL,将lock设置为O_NONBLOCK。
  n 异步I/O:可将cmd设置为F_SETFL,将lock设置为O_ASYNC。
  下面是用fcntl()将套接字设置为非阻塞I/O的实例代码:
  /* net_fcntl.c */
  #include 《sys/types.h》
  #include 《sys/socket.h》
  #include 《sys/wait.h》
  #include 《stdio.h》
  #include 《stdlib.h》
  #include 《errno.h》
  #include 《string.h》
  #include 《sys/un.h》
  #include 《sys/time.h》
  #include 《sys/ioctl.h》
  #include 《unistd.h》
  #include 《netinet/in.h》
  #include 《fcntl.h》
  #define PORT 1234
  #define MAX_QUE_CONN_NM 5
  #define BUFFER_SIZE 1024
  int main()
  {
  struct sockaddr_in server_sockaddr, client_sockaddr;
  int sin_size, recvbytes, flags;
  int sockfd, client_fd;
  char buf[BUFFER_SIZE];
  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  {
  perror(“socket”);
  exit(1);
  }
  server_sockaddr.sin_family = AF_INET;
  server_sockaddr.sin_port = htons(PORT);
  server_sockaddr.sin_addr.s_addr = INADDR_ANY;
  bzero(&(server_sockaddr.sin_zero), 8);
  int i = 1;/* 允许重复使用本地地址与套接字进行绑定 */
  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
  if (bind(sockfd, (struct sockaddr *)&server_sockaddr,
  sizeof(struct sockaddr)) == -1)
  {
  perror(“bind”);
  exit(1);
  }
  if(listen(sockfd,MAX_QUE_CONN_NM) == -1)
  {
  perror(“listen”);
  exit(1);
  }
  printf(“Listening.。..\n”);
  /* 调用fcntl()函数给套接字设置非阻塞属性 */
  flags = fcntl(sockfd, F_GETFL);
  if (flags 《 0 || fcntl(sockfd, F_SETFL, flags|O_NONBLOCK) 《 0)
  {
  perror(“fcntl”);
  exit(1);
  }
  while(1)
  {
  sin_size = sizeof(struct sockaddr_in);
  if ((client_fd = accept(sockfd,
  (struct sockaddr*)&client_sockaddr, &sin_size)) 《 0)
  {
  perror(“accept”);
  exit(1);
  }
  if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) 《 0)
  {
  perror(“recv”);
  exit(1);
  }
  printf(“Received a message: %s\n”, buf);
  } /*while*/
  close(client_fd);
  exit(1);
  }
  运行该程序,结果如下所示:
  $ 。/net_fcntl
  Listening.。..
  accept: Resource temporarily unavailable
  可以看到,当accept()的资源不可用(没有任何未处理的等待连接的

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !