免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2763 | 回复: 2
打印 上一主题 下一主题

[C] C 实现 HTML5服务解析功能,遇到个socket客户端是否初次连接服务器的握手判断... [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-04-09 13:38 |只看该作者 |倒序浏览
下面是服务器接受函数的代码:

如果是某个客户端第一次连接服务器,则建立握手先,以后,该连接除非重新连接服务器再,则不需要握手动作,做普通SOCKET通信

但是,下面代码作判断时,服务器只能与一个客户端建立连接,其他客户端就不能再连接上了,服务建立握手...

当多个客户端存在时,如何判断每一个客户端是否是第一次与服务器连接,以便建立握手?
  1. // receive data  
  2. void RecvData(int fd, int events, void *arg)  
  3. {
  4.                 unsigned char ret_len;
  5.                 unsigned char send_str[254];                       
  6.     struct myevent_s *ev = (struct myevent_s*)arg;  
  7.     int len,i;  
  8.       
  9.     memset(ev->buff,0,REQUEST_LEN_MAX);
  10.     len = recv(fd, ev->buff, sizeof(ev->buff), 0);
  11.     //printf("---------------------\n");
  12.     printf("recv data len: %d\n",len);
  13.     //printf("---------------------\n");
  14.     //printf("recv data content: %s\n",ev->buff);
  15.     printf("\n");
  16.     if(len<480){
  17.             //printf("recv data content:\n");
  18.             for(i=0;i<len;i++)
  19.                     printf("%02x ",ev->buff[i]);
  20.             }
  21.    
  22.     printf("\n");
  23.     if((0==connected))// [color=Red]目前只能接受一个客户端的连接握手,当第二个客户端请求连接时,就走不到握手协议这里,也就无法建立连接....[/color]
  24.                   {                         
  25.                                 printf(" shakehand is ok %d \n",fd);
  26.                     //printf("read:%d\n%s\n",len,ev->buff);
  27.                     secWebSocketKey=computeAcceptKey(ev->buff);       
  28.                     shakeHand(fd,secWebSocketKey);
  29.                     connected=1;
  30.                     //printf("22222    connected is :%d \n",connected);
  31.                     //continue;
  32.                   }
  33.                   /*
  34.                 data=analyData(ev->buff,len);
  35.                 printf("data conent: %s \n",ev->buff);
  36.                 printf("data len: %d \n",len);
  37.                 response(fd,data);
  38.          */
  39.          if(len<254){
  40.          ret_len=analyData_2(ev->buff,len,send_str);
  41.        
  42.                  //printf("254 content:\n");
  43.             //for(i=0;i<ret_len;i++)
  44.                     //printf("%02x ",send_str[i]);
  45.         }         
  46.     if(len==6 & ev->buff[0]==0x88)//页面上断开连接
  47.             {
  48.                     //printf("3333    connected is :%d \n",connected);
  49.                     connected=0;
  50.                     close(ev->fd);  
  51.         printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);
  52.                     //printf("4444    connected is :%d \n",connected);                   
  53.                     }
  54.     if(len > 0)
  55.     {
  56.             ev->buff[0]=0x81;
  57.                         ev->buff[1]=12;               
  58.                         ev->buff[2]=0x46;
  59.                         ev->buff[3]=0x30;
  60.                         ev->buff[4]=0x30;
  61.                         ev->buff[5]=0x36;
  62.                         ev->buff[6]=0x45;
  63.                         ev->buff[7]=0x45;
  64.                         ev->buff[8]=0x30;
  65.                         ev->buff[9]=0x31;
  66.                         ev->buff[10]=0x32;
  67.                         ev->buff[11]=0x33;
  68.                         ev->buff[12]=0x42;
  69.                         ev->buff[13]=0x43;
  70.                         ev->buff[14]=0x42;
  71.                         ev->buff[15]=0x43;
  72.                
  73.         ev->len += len;      
  74.         printf("\n");
  75.         //ev->buff[0]=buffer[0];
  76.         //ev->buff[1]=buffer[1];
  77.         //memcpy(ev->buff,buffer,buffer[1]+2);
  78.         ev->len=14;
  79.         ev->call_back = SendData;
  80.         // change to send event  
  81.         //EventSet(ev, fd, SendData, ev);  
  82.         EventAdd(g_epollFd, EPOLLOUT, ev);
  83.     }  
  84.     else if(len == 0)  
  85.     {  
  86.         close(ev->fd);  
  87.         printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);  
  88.     }  
  89.     else  
  90.     {  
  91.         close(ev->fd);  
  92.         printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));  
  93.     }  
  94. }  
复制代码
相对全点的代码:

  1. #define REQUEST_LEN_MAX 1024
  2. #define DEFEULT_SERVER_PORT 8000
  3. #define WEB_SOCKET_KEY_LEN_MAX 256
  4. #define RESPONSE_HEADER_LEN_MAX 1024
  5. #define LINE_MAX 256
  6. #define HOST_IP_ADDRESS_TCP "192.168.34.52"
  7. #define MAX_EVENTS 500  
  8. #define HOST_PORT_TCP 4530

  9. int connected=0;//0:not connect.1:connected.
  10. char *data;
  11. char *secWebSocketKey;

  12. void shakeHand(int connfd,const char *serverKey);
  13. char * fetchSecKey(const char * buf);
  14. char * computeAcceptKey(const char * buf);
  15. char * analyData(const char * buf,const int bufLen);
  16. char * packData(const char * message,unsigned long * len);
  17. void response(const int connfd,const char * message);
  18. unsigned char analyData_2( char * buf, int bufLen,char* payloadData );

  19. struct myevent_s  
  20. {  
  21.     int fd;  
  22.     void (*call_back)(int fd, int events, void *arg);  
  23.     int events;  
  24.     void *arg;  
  25.     int status; // 1: in epoll wait list, 0 not in  
  26.     unsigned char buff[1024]; // recv data buffer  
  27.     int len, s_offset;  
  28.     long last_active; // last active time
  29. };  
  30. // set event  
  31. void EventSet(struct myevent_s *ev, int fd, void (*call_back)(int, int, void*), void *arg)  
  32. {  
  33.     ev->fd = fd;  
  34.     ev->call_back = call_back;  
  35.     ev->events = 0;  
  36.     ev->arg = arg;
  37.     ev->status = 0;
  38.     bzero(ev->buff, sizeof(ev->buff));
  39.     ev->s_offset = 0;  
  40.     ev->len = 0;
  41.     ev->last_active = time(NULL);  
  42. }  
  43. // add/mod an event to epoll  
  44. void EventAdd(int epollFd, int events, struct myevent_s *ev)  
  45. {  
  46.     struct epoll_event epv = {0, {0}};  
  47.     int op;  
  48.     epv.data.ptr = ev;  
  49.     epv.events = ev->events = events;  
  50.     if(ev->status == 1){  
  51.         op = EPOLL_CTL_MOD;  
  52.     }  
  53.     else{
  54.         op = EPOLL_CTL_ADD;  
  55.         ev->status = 1;
  56.     }  
  57.     if(epoll_ctl(epollFd, op, ev->fd, &epv) < 0)  
  58.         printf("Event Add failed[fd=%d], evnets[%d]\n", ev->fd, events);  
  59.     else  
  60.         printf("Event Add OK[fd=%d], op=%d, evnets[%0X], status:[%d]\n", ev->fd, op, events, ev->status);  
  61. }  
  62. // delete an event from epoll  
  63. void EventDel(int epollFd, struct myevent_s *ev)  
  64. {  
  65.     struct epoll_event epv = {0, {0}};  
  66.     if(ev->status != 1) return;  
  67.     epv.data.ptr = ev;  
  68.     ev->status = 0;
  69.     epoll_ctl(epollFd, EPOLL_CTL_DEL, ev->fd, &epv);  
  70. }  
  71. int g_epollFd;  
  72. struct myevent_s g_Events[MAX_EVENTS+1]; // g_Events[MAX_EVENTS] is used by listen fd  
  73. void RecvData(int fd, int events, void *arg);  
  74. void SendData(int fd, int events, void *arg);  

  75. // accept new connections from clients  
  76. void AcceptConn(int fd, int events, void *arg)  
  77. {  
  78.     struct sockaddr_in sin;  
  79.     socklen_t len = sizeof(struct sockaddr_in);  
  80.     int nfd, i;  
  81.     // accept  
  82.     if((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -1)  
  83.     {  
  84.         if(errno != EAGAIN && errno != EINTR)  
  85.         {  
  86.         }
  87.         printf("%s: accept, %d", __func__, errno);  
  88.         return;  
  89.     }  
  90.     do  
  91.     {  
  92.         for(i = 0; i < MAX_EVENTS; i++)  
  93.         {  
  94.             if(g_Events[i].status == 0)  
  95.             {  
  96.                 break;  
  97.             }  
  98.         }  
  99.         if(i == MAX_EVENTS)  
  100.         {  
  101.             printf("%s:max connection limit[%d].", __func__, MAX_EVENTS);  
  102.             break;  
  103.         }  
  104.         // set nonblocking
  105.         int iret = 0;
  106.         if((iret = fcntl(nfd, F_SETFL, O_NONBLOCK)) < 0)
  107.         {
  108.             printf("%s: fcntl nonblocking failed:%d", __func__, iret);
  109.             break;
  110.         }
  111.         // add a read event for receive data  
  112.         EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]);  
  113.         EventAdd(g_epollFd, EPOLLIN, &g_Events[i]);
  114.     }while(0);  
  115.    
  116.     printf("new conn %s, %d,time:%ld, pos:%d \n", inet_ntoa(sin.sin_addr),
  117.             ntohs(sin.sin_port), g_Events[i].last_active, i);
  118. }  
  119. // receive data  
  120. void RecvData(int fd, int events, void *arg)  
  121. {
  122.                 unsigned char ret_len;
  123.                 unsigned char send_str[254];                       
  124.     struct myevent_s *ev = (struct myevent_s*)arg;  
  125.     int len,i;  
  126.       
  127.     memset(ev->buff,0,REQUEST_LEN_MAX);
  128.     len = recv(fd, ev->buff, sizeof(ev->buff), 0);
  129.     //printf("---------------------\n");
  130.     printf("recv data len: %d\n",len);
  131.     //printf("---------------------\n");
  132.     //printf("recv data content: %s\n",ev->buff);
  133.     printf("\n");
  134.     if(len<480){
  135.             //printf("recv data content:\n");
  136.             for(i=0;i<len;i++)
  137.                     printf("%02x ",ev->buff[i]);
  138.             }
  139.    
  140.     printf("\n");
  141.     if((0==connected))
  142.                   {                         
  143.                                 printf(" shakehand is ok %d \n",fd);
  144.                     //printf("read:%d\n%s\n",len,ev->buff);
  145.                     secWebSocketKey=computeAcceptKey(ev->buff);       
  146.                     shakeHand(fd,secWebSocketKey);
  147.                     connected=1;
  148.                     //printf("22222    connected is :%d \n",connected);
  149.                     //continue;
  150.                   }
  151.                   /*
  152.                 data=analyData(ev->buff,len);
  153.                 printf("data conent: %s \n",ev->buff);
  154.                 printf("data len: %d \n",len);
  155.                 response(fd,data);
  156.          */
  157.          if(len<254){
  158.          ret_len=analyData_2(ev->buff,len,send_str);
  159.        
  160.                  //printf("254 content:\n");
  161.             //for(i=0;i<ret_len;i++)
  162.                     //printf("%02x ",send_str[i]);
  163.         }         
  164.     if(len==6 & ev->buff[0]==0x88)//页面上断开连接
  165.             {
  166.                     //printf("3333    connected is :%d \n",connected);
  167.                     connected=0;
  168.                     close(ev->fd);  
  169.         printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);
  170.                     //printf("4444    connected is :%d \n",connected);                   
  171.                     }
  172.     if(len > 0)
  173.     {
  174.             ev->buff[0]=0x81;
  175.                         ev->buff[1]=12;               
  176.                         ev->buff[2]=0x46;
  177.                         ev->buff[3]=0x30;
  178.                         ev->buff[4]=0x30;
  179.                         ev->buff[5]=0x36;
  180.                         ev->buff[6]=0x45;
  181.                         ev->buff[7]=0x45;
  182.                         ev->buff[8]=0x30;
  183.                         ev->buff[9]=0x31;
  184.                         ev->buff[10]=0x32;
  185.                         ev->buff[11]=0x33;
  186.                         ev->buff[12]=0x42;
  187.                         ev->buff[13]=0x43;
  188.                         ev->buff[14]=0x42;
  189.                         ev->buff[15]=0x43;
  190.                
  191.         ev->len += len;      
  192.         printf("\n");
  193.         //ev->buff[0]=buffer[0];
  194.         //ev->buff[1]=buffer[1];
  195.         //memcpy(ev->buff,buffer,buffer[1]+2);
  196.         ev->len=14;
  197.         ev->call_back = SendData;
  198.         // change to send event  
  199.         //EventSet(ev, fd, SendData, ev);  
  200.         EventAdd(g_epollFd, EPOLLOUT, ev);
  201.     }  
  202.     else if(len == 0)  
  203.     {  
  204.         close(ev->fd);  
  205.         printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);  
  206.     }  
  207.     else  
  208.     {  
  209.         close(ev->fd);  
  210.         printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));  
  211.     }  
  212. }  
  213. // send data  
  214. void SendData(int fd, int events, void *arg)  
  215. {  
  216.     struct myevent_s *ev = (struct myevent_s*)arg;  
  217.     int len,i;  
  218.     // send data  
  219.     len = send(fd, ev->buff + ev->s_offset, ev->len - ev->s_offset, 0);
  220.     if(len > 0)
  221.     {
  222.         //printf("send[fd=%d], [%d<->%d]%s\n", fd, len, ev->len, ev->buff);
  223.         printf("send data is :\n");
  224.         for(i=0;i<ev->buff[1]+2;i++)
  225.                 printf("  %02X", ev->buff[i]);
  226.         printf("\n");
  227.         ev->s_offset += len;
  228.         if(ev->s_offset == ev->len)
  229.         {
  230.             // change to receive event
  231.             EventDel(g_epollFd, ev);
  232.             EventSet(ev, fd, RecvData, ev);  
  233.             EventAdd(g_epollFd, EPOLLIN, ev);  
  234.         }
  235.     }
  236.     else  
  237.     {  
  238.         close(ev->fd);  
  239.         EventDel(g_epollFd, ev);  
  240.         printf("send[fd=%d] error[%d]\n", fd, errno);  
  241.     }  
  242. }  

  243. void InitListenSocket(int epollFd, short port,char* ip)  
  244. {  
  245.     int listenFd = socket(AF_INET, SOCK_STREAM, 0);  
  246.     fcntl(listenFd, F_SETFL, O_NONBLOCK); // set non-blocking  
  247.     printf("server listen fd=%d\n", listenFd);  
  248.     EventSet(&g_Events[MAX_EVENTS], listenFd, AcceptConn, &g_Events[MAX_EVENTS]);  
  249.     // add listen socket  
  250.     EventAdd(epollFd, EPOLLIN, &g_Events[MAX_EVENTS]);  
  251.     // bind & listen  
  252.     struct sockaddr_in sin;  
  253.     bzero(&sin, sizeof(sin));  
  254.     sin.sin_family = AF_INET;  
  255.     //sin.sin_addr.s_addr = INADDR_ANY;  
  256.     //sin.sin_addr.s_addr = inet_addr(HOST_IP_ADDRESS_TCP);
  257.     sin.sin_addr.s_addr = inet_addr(ip);
  258.     sin.sin_port = htons(port);  
  259.     bind(listenFd, (struct sockaddr*)&sin, sizeof(sin));  
  260.     listen(listenFd, 5);
  261.     printf("server ip is : %s \n",ip);
  262. }  

  263. int main(int argc, char *argv[])
  264. {
  265.         struct sockaddr_in servaddr, cliaddr;
  266.         socklen_t cliaddr_len;
  267.         int listenfd, connfd;
  268.         char buf[REQUEST_LEN_MAX];
  269.         char *data;
  270.         char str[INET_ADDRSTRLEN];
  271.         char *secWebSocketKey;
  272.         int i,n;
  273.         //int connected=0;//0:not connect.1:connected.
  274.        
  275.         int port= DEFEULT_SERVER_PORT;

  276.         if(argc>1)
  277.           {
  278.             port=atoi(argv[1]);
  279.           }
  280.         if(port<=0||port>0xFFFF)
  281.           {
  282.             printf("Port(%d) is out of range(1-%d)\n",port,0xFFFF);
  283.             return;
  284.           }
  285.           // create epoll ///////////////////////
  286.     g_epollFd = epoll_create(MAX_EVENTS);  
  287.     if(g_epollFd <= 0) printf("create epoll failed.%d\n", g_epollFd);  
  288.     // create & bind listen socket, and add to epoll, set non-blocking  
  289.     InitListenSocket(g_epollFd, HOST_PORT_TCP,HOST_IP_ADDRESS_TCP);
  290.     // event loop  
  291.     struct epoll_event events[MAX_EVENTS];  
  292.     printf("server running:port[%d]\n", HOST_PORT_TCP);  
  293.     int checkPos = 0;
  294.           /////////////////////////////////
  295.          
  296.         while (1)
  297.           {
  298.                  
  299.                   // wait for events to happen  
  300.         int fds = epoll_wait(g_epollFd, events, MAX_EVENTS, 1000);  
  301.         if(fds < 0){
  302.             printf("epoll_wait error, exit\n");  
  303.             break;  
  304.         }
  305.        for( i = 0; i < fds; i++){
  306.                   struct myevent_s *ev = (struct myevent_s*)events[i].data.ptr;  
  307.             if((events[i].events&EPOLLIN)&&(ev->events&EPOLLIN)) // read event  
  308.             {  
  309.                 ev->call_back(ev->fd, events[i].events, ev->arg);  
  310.             }  
  311.             if((events[i].events&EPOLLOUT)&&(ev->events&EPOLLOUT)) // write event  
  312.             {  
  313.                 ev->call_back(ev->fd, events[i].events, ev->arg);  
  314.             }  
  315.         }               
  316.         }//while
  317.         close(connfd);
  318. }
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2015-04-09 13:47 |只看该作者
程序都是网找 的

都还没完全理解....

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
3 [报告]
发表于 2015-04-10 16:25 |只看该作者
sasinop 发表于 2015-04-09 13:47
程序都是网找 的

都还没完全理解....

你那个:
connected。。。。。
不应该是全局的,应该是每个客户端一个。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP