Chinaunix首页 | 论坛 | 博客
  • 博客访问: 63773
  • 博文数量: 9
  • 博客积分: 417
  • 博客等级: 入伍新兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-12 13:07
文章分类

全部博文(9)

文章存档

2017年(1)

2012年(2)

2011年(6)

分类: C/C++

2011-08-09 23:39:05

1、先总结一下常用API的函数原型。
  1. socklen_t socket(int nFileds,int nType,int nFlag);
  2. int bind(int nSocket,sockaddr *pAddr,int nLen);
  3. int listen(int nSocket,int nListenNum);
  4. int accept(int nSocket,socketaddr *pAddr,int *pnLen);
socket 的API定义包含在头文件 sys/socket.h,数据类型定义在 sys/types.h
sockaddr以及sockaddr_in结构体的定义在头文件 netinet/in.h
IP地址转换的时候用到的字符串和DWORD值转换函数inet_addr(char*),inet_ntoa(sockaddr_in addr)包含在arpa/inet.h
 
设置套接字为非阻塞套接字,使用函数int fcntl(int nFd,int nCmd,...),该函数包含在头文件fcntl.h中
 
信号处理函数的设置采用函数sighandler_t signal(int nSig,void(*DealFun)(int nSig)),该函数包含在头文件signal.h中
 
今天想测试一下socket编程中,信号驱动方式的使用,不知道原因在哪儿,信号貌似收不到。。。。先贴代码。。。
代码已经修改完毕,能够正常通信,服务器采用tcp连接,当socket有连接的时候,受到内核的信号SIGIO。
函数后面的accept是想确认一下,在异步通信的时候,这些函数是不是阻塞的,果然是,虽然设置socket为O_ASYNC。
 
  1. #include<stdio.h>
  2. #include<sys/socket.h>
  3. #include<sys/types.h>
  4. #include<sys/signal.h>
  5. #include<fcntl.h>
  6. #include<string.h>
  7. #include<netinet/in.h>
  8. #include<arpa/inet.h>
  9. #include<unistd.h>

  10. #define MAX_LISTEN_NUM 10
  11. #define MAX_CONNECT_NUM 128
  12. #define LISTEN_PORT 12345

  13. static int g_nCount =0;
  14. void DealSignalIO(int nSig)
  15. {
  16.     printf("nSig (%d) == SIGIO(%d) \n",nSig,SIGIO);
  17.     printf("SignalIO count: %d\n",g_nCount++);
  18. }
  19. int main()
  20. {
  21.     
  22.     int nListenSocket = 0,nSubSocket[MAX_CONNECT_NUM],nRet = 0;
  23.     nListenSocket = socket(AF_INET,SOCK_STREAM,0);
  24.     if(-1 == nListenSocket)
  25.     {
  26.         perror("socket ");
  27.         return -1;
  28.     }
  29.     sockaddr_in MyAddr;
  30.     MyAddr.sin_addr.s_addr = inet_addr("10.10.148.146");
  31.     MyAddr.sin_port = htons(LISTEN_PORT);
  32.     nRet = bind(nListenSocket,(sockaddr*)&MyAddr,sizeof(sockaddr));
  33.     if(-1 == nRet)
  34.     {
  35.         perror("bind ");
  36.         return -1;
  37.     }
  38.     nRet = listen(nListenSocket,MAX_LISTEN_NUM);
  39.     if(-1 == nRet)
  40.     {
  41.         perror("listen");
  42.         return -1;
  43.     }

  44.     //set the socket not block
  45.     //nRet = fcntl(nListenSocket,F_SETFL,O_NONBLOCK);
  46.     //set the socket asynchronous
  47.     nRet = fcntl(nListenSocket,F_SETFL,O_ASYNC);
  48.     if(-1 == nRet)
  49.     {
  50.         perror("fcntl ");
  51.         return -1;
  52.     }
  53.     //set the SIGIO deal function
  54.     signal(SIGIO,DealSignalIO);
  55.     //set the signal's owner
  56.     nRet = fcntl(nListenSocket,F_SETOWN,getpid());
  57.     if(-1 == nRet)
  58.     {
  59.         perror("fcntl ");
  60.         return -1;
  61.     }

  62.     //accept
  63.     int nLen = 0;
  64.     nRet = accept(nListenSocket,(sockaddr*)&MyAddr,(socklen_t*)&nLen);
  65.     if(-1 == nRet)
  66.     {
  67.         perror("accept ");
  68.     }
  69.     else
  70.     {
  71.         printf("test if accept is blocked \n");
  72.     }


  73.     while(1)
  74.     sleep(2);
  75.         
  76.     return 0;
  77. }
 
阅读(3020) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

jiayanfu2011-08-10 11:23:28

在实现信号驱动异步IO的时候,关键是要通过fcntl设置socket的异步属性,然后通过fcntl设置socket的主属。

在实现的时候,信号设置函数signal应该在设置socket的主属之前调用,避免发生信号丢失