- 论坛徽章:
- 1
|
下面是服务器接受函数的代码:
如果是某个客户端第一次连接服务器,则建立握手先,以后,该连接除非重新连接服务器再,则不需要握手动作,做普通SOCKET通信
但是,下面代码作判断时,服务器只能与一个客户端建立连接,其他客户端就不能再连接上了,服务建立握手...
当多个客户端存在时,如何判断每一个客户端是否是第一次与服务器连接,以便建立握手?- // receive data
- void RecvData(int fd, int events, void *arg)
- {
- unsigned char ret_len;
- unsigned char send_str[254];
- struct myevent_s *ev = (struct myevent_s*)arg;
- int len,i;
-
- memset(ev->buff,0,REQUEST_LEN_MAX);
- len = recv(fd, ev->buff, sizeof(ev->buff), 0);
- //printf("---------------------\n");
- printf("recv data len: %d\n",len);
- //printf("---------------------\n");
- //printf("recv data content: %s\n",ev->buff);
- printf("\n");
- if(len<480){
- //printf("recv data content:\n");
- for(i=0;i<len;i++)
- printf("%02x ",ev->buff[i]);
- }
-
- printf("\n");
- if((0==connected))// [color=Red]目前只能接受一个客户端的连接握手,当第二个客户端请求连接时,就走不到握手协议这里,也就无法建立连接....[/color]
- {
- printf(" shakehand is ok %d \n",fd);
- //printf("read:%d\n%s\n",len,ev->buff);
- secWebSocketKey=computeAcceptKey(ev->buff);
- shakeHand(fd,secWebSocketKey);
- connected=1;
- //printf("22222 connected is :%d \n",connected);
- //continue;
- }
- /*
- data=analyData(ev->buff,len);
- printf("data conent: %s \n",ev->buff);
- printf("data len: %d \n",len);
- response(fd,data);
- */
- if(len<254){
- ret_len=analyData_2(ev->buff,len,send_str);
-
- //printf("254 content:\n");
- //for(i=0;i<ret_len;i++)
- //printf("%02x ",send_str[i]);
- }
- if(len==6 & ev->buff[0]==0x88)//页面上断开连接
- {
- //printf("3333 connected is :%d \n",connected);
- connected=0;
- close(ev->fd);
- printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);
- //printf("4444 connected is :%d \n",connected);
- }
- if(len > 0)
- {
- ev->buff[0]=0x81;
- ev->buff[1]=12;
- ev->buff[2]=0x46;
- ev->buff[3]=0x30;
- ev->buff[4]=0x30;
- ev->buff[5]=0x36;
- ev->buff[6]=0x45;
- ev->buff[7]=0x45;
- ev->buff[8]=0x30;
- ev->buff[9]=0x31;
- ev->buff[10]=0x32;
- ev->buff[11]=0x33;
- ev->buff[12]=0x42;
- ev->buff[13]=0x43;
- ev->buff[14]=0x42;
- ev->buff[15]=0x43;
-
- ev->len += len;
- printf("\n");
- //ev->buff[0]=buffer[0];
- //ev->buff[1]=buffer[1];
- //memcpy(ev->buff,buffer,buffer[1]+2);
- ev->len=14;
- ev->call_back = SendData;
- // change to send event
- //EventSet(ev, fd, SendData, ev);
- EventAdd(g_epollFd, EPOLLOUT, ev);
- }
- else if(len == 0)
- {
- close(ev->fd);
- printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);
- }
- else
- {
- close(ev->fd);
- printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));
- }
- }
复制代码 相对全点的代码:
- #define REQUEST_LEN_MAX 1024
- #define DEFEULT_SERVER_PORT 8000
- #define WEB_SOCKET_KEY_LEN_MAX 256
- #define RESPONSE_HEADER_LEN_MAX 1024
- #define LINE_MAX 256
- #define HOST_IP_ADDRESS_TCP "192.168.34.52"
- #define MAX_EVENTS 500
- #define HOST_PORT_TCP 4530
- int connected=0;//0:not connect.1:connected.
- char *data;
- char *secWebSocketKey;
- void shakeHand(int connfd,const char *serverKey);
- char * fetchSecKey(const char * buf);
- char * computeAcceptKey(const char * buf);
- char * analyData(const char * buf,const int bufLen);
- char * packData(const char * message,unsigned long * len);
- void response(const int connfd,const char * message);
- unsigned char analyData_2( char * buf, int bufLen,char* payloadData );
- struct myevent_s
- {
- int fd;
- void (*call_back)(int fd, int events, void *arg);
- int events;
- void *arg;
- int status; // 1: in epoll wait list, 0 not in
- unsigned char buff[1024]; // recv data buffer
- int len, s_offset;
- long last_active; // last active time
- };
- // set event
- void EventSet(struct myevent_s *ev, int fd, void (*call_back)(int, int, void*), void *arg)
- {
- ev->fd = fd;
- ev->call_back = call_back;
- ev->events = 0;
- ev->arg = arg;
- ev->status = 0;
- bzero(ev->buff, sizeof(ev->buff));
- ev->s_offset = 0;
- ev->len = 0;
- ev->last_active = time(NULL);
- }
- // add/mod an event to epoll
- void EventAdd(int epollFd, int events, struct myevent_s *ev)
- {
- struct epoll_event epv = {0, {0}};
- int op;
- epv.data.ptr = ev;
- epv.events = ev->events = events;
- if(ev->status == 1){
- op = EPOLL_CTL_MOD;
- }
- else{
- op = EPOLL_CTL_ADD;
- ev->status = 1;
- }
- if(epoll_ctl(epollFd, op, ev->fd, &epv) < 0)
- printf("Event Add failed[fd=%d], evnets[%d]\n", ev->fd, events);
- else
- printf("Event Add OK[fd=%d], op=%d, evnets[%0X], status:[%d]\n", ev->fd, op, events, ev->status);
- }
- // delete an event from epoll
- void EventDel(int epollFd, struct myevent_s *ev)
- {
- struct epoll_event epv = {0, {0}};
- if(ev->status != 1) return;
- epv.data.ptr = ev;
- ev->status = 0;
- epoll_ctl(epollFd, EPOLL_CTL_DEL, ev->fd, &epv);
- }
- int g_epollFd;
- struct myevent_s g_Events[MAX_EVENTS+1]; // g_Events[MAX_EVENTS] is used by listen fd
- void RecvData(int fd, int events, void *arg);
- void SendData(int fd, int events, void *arg);
- // accept new connections from clients
- void AcceptConn(int fd, int events, void *arg)
- {
- struct sockaddr_in sin;
- socklen_t len = sizeof(struct sockaddr_in);
- int nfd, i;
- // accept
- if((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -1)
- {
- if(errno != EAGAIN && errno != EINTR)
- {
- }
- printf("%s: accept, %d", __func__, errno);
- return;
- }
- do
- {
- for(i = 0; i < MAX_EVENTS; i++)
- {
- if(g_Events[i].status == 0)
- {
- break;
- }
- }
- if(i == MAX_EVENTS)
- {
- printf("%s:max connection limit[%d].", __func__, MAX_EVENTS);
- break;
- }
- // set nonblocking
- int iret = 0;
- if((iret = fcntl(nfd, F_SETFL, O_NONBLOCK)) < 0)
- {
- printf("%s: fcntl nonblocking failed:%d", __func__, iret);
- break;
- }
- // add a read event for receive data
- EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]);
- EventAdd(g_epollFd, EPOLLIN, &g_Events[i]);
- }while(0);
-
- printf("new conn %s, %d,time:%ld, pos:%d \n", inet_ntoa(sin.sin_addr),
- ntohs(sin.sin_port), g_Events[i].last_active, i);
- }
- // receive data
- void RecvData(int fd, int events, void *arg)
- {
- unsigned char ret_len;
- unsigned char send_str[254];
- struct myevent_s *ev = (struct myevent_s*)arg;
- int len,i;
-
- memset(ev->buff,0,REQUEST_LEN_MAX);
- len = recv(fd, ev->buff, sizeof(ev->buff), 0);
- //printf("---------------------\n");
- printf("recv data len: %d\n",len);
- //printf("---------------------\n");
- //printf("recv data content: %s\n",ev->buff);
- printf("\n");
- if(len<480){
- //printf("recv data content:\n");
- for(i=0;i<len;i++)
- printf("%02x ",ev->buff[i]);
- }
-
- printf("\n");
- if((0==connected))
- {
- printf(" shakehand is ok %d \n",fd);
- //printf("read:%d\n%s\n",len,ev->buff);
- secWebSocketKey=computeAcceptKey(ev->buff);
- shakeHand(fd,secWebSocketKey);
- connected=1;
- //printf("22222 connected is :%d \n",connected);
- //continue;
- }
- /*
- data=analyData(ev->buff,len);
- printf("data conent: %s \n",ev->buff);
- printf("data len: %d \n",len);
- response(fd,data);
- */
- if(len<254){
- ret_len=analyData_2(ev->buff,len,send_str);
-
- //printf("254 content:\n");
- //for(i=0;i<ret_len;i++)
- //printf("%02x ",send_str[i]);
- }
- if(len==6 & ev->buff[0]==0x88)//页面上断开连接
- {
- //printf("3333 connected is :%d \n",connected);
- connected=0;
- close(ev->fd);
- printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);
- //printf("4444 connected is :%d \n",connected);
- }
- if(len > 0)
- {
- ev->buff[0]=0x81;
- ev->buff[1]=12;
- ev->buff[2]=0x46;
- ev->buff[3]=0x30;
- ev->buff[4]=0x30;
- ev->buff[5]=0x36;
- ev->buff[6]=0x45;
- ev->buff[7]=0x45;
- ev->buff[8]=0x30;
- ev->buff[9]=0x31;
- ev->buff[10]=0x32;
- ev->buff[11]=0x33;
- ev->buff[12]=0x42;
- ev->buff[13]=0x43;
- ev->buff[14]=0x42;
- ev->buff[15]=0x43;
-
- ev->len += len;
- printf("\n");
- //ev->buff[0]=buffer[0];
- //ev->buff[1]=buffer[1];
- //memcpy(ev->buff,buffer,buffer[1]+2);
- ev->len=14;
- ev->call_back = SendData;
- // change to send event
- //EventSet(ev, fd, SendData, ev);
- EventAdd(g_epollFd, EPOLLOUT, ev);
- }
- else if(len == 0)
- {
- close(ev->fd);
- printf("[fd=%d] pos[%d], closed gracefully.\n", fd, ev-g_Events);
- }
- else
- {
- close(ev->fd);
- printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));
- }
- }
- // send data
- void SendData(int fd, int events, void *arg)
- {
- struct myevent_s *ev = (struct myevent_s*)arg;
- int len,i;
- // send data
- len = send(fd, ev->buff + ev->s_offset, ev->len - ev->s_offset, 0);
- if(len > 0)
- {
- //printf("send[fd=%d], [%d<->%d]%s\n", fd, len, ev->len, ev->buff);
- printf("send data is :\n");
- for(i=0;i<ev->buff[1]+2;i++)
- printf(" %02X", ev->buff[i]);
- printf("\n");
- ev->s_offset += len;
- if(ev->s_offset == ev->len)
- {
- // change to receive event
- EventDel(g_epollFd, ev);
- EventSet(ev, fd, RecvData, ev);
- EventAdd(g_epollFd, EPOLLIN, ev);
- }
- }
- else
- {
- close(ev->fd);
- EventDel(g_epollFd, ev);
- printf("send[fd=%d] error[%d]\n", fd, errno);
- }
- }
- void InitListenSocket(int epollFd, short port,char* ip)
- {
- int listenFd = socket(AF_INET, SOCK_STREAM, 0);
- fcntl(listenFd, F_SETFL, O_NONBLOCK); // set non-blocking
- printf("server listen fd=%d\n", listenFd);
- EventSet(&g_Events[MAX_EVENTS], listenFd, AcceptConn, &g_Events[MAX_EVENTS]);
- // add listen socket
- EventAdd(epollFd, EPOLLIN, &g_Events[MAX_EVENTS]);
- // bind & listen
- struct sockaddr_in sin;
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
- //sin.sin_addr.s_addr = INADDR_ANY;
- //sin.sin_addr.s_addr = inet_addr(HOST_IP_ADDRESS_TCP);
- sin.sin_addr.s_addr = inet_addr(ip);
- sin.sin_port = htons(port);
- bind(listenFd, (struct sockaddr*)&sin, sizeof(sin));
- listen(listenFd, 5);
- printf("server ip is : %s \n",ip);
- }
- int main(int argc, char *argv[])
- {
- struct sockaddr_in servaddr, cliaddr;
- socklen_t cliaddr_len;
- int listenfd, connfd;
- char buf[REQUEST_LEN_MAX];
- char *data;
- char str[INET_ADDRSTRLEN];
- char *secWebSocketKey;
- int i,n;
- //int connected=0;//0:not connect.1:connected.
-
- int port= DEFEULT_SERVER_PORT;
- if(argc>1)
- {
- port=atoi(argv[1]);
- }
- if(port<=0||port>0xFFFF)
- {
- printf("Port(%d) is out of range(1-%d)\n",port,0xFFFF);
- return;
- }
- // create epoll ///////////////////////
- g_epollFd = epoll_create(MAX_EVENTS);
- if(g_epollFd <= 0) printf("create epoll failed.%d\n", g_epollFd);
- // create & bind listen socket, and add to epoll, set non-blocking
- InitListenSocket(g_epollFd, HOST_PORT_TCP,HOST_IP_ADDRESS_TCP);
- // event loop
- struct epoll_event events[MAX_EVENTS];
- printf("server running:port[%d]\n", HOST_PORT_TCP);
- int checkPos = 0;
- /////////////////////////////////
-
- while (1)
- {
-
- // wait for events to happen
- int fds = epoll_wait(g_epollFd, events, MAX_EVENTS, 1000);
- if(fds < 0){
- printf("epoll_wait error, exit\n");
- break;
- }
- for( i = 0; i < fds; i++){
- struct myevent_s *ev = (struct myevent_s*)events[i].data.ptr;
- if((events[i].events&EPOLLIN)&&(ev->events&EPOLLIN)) // read event
- {
- ev->call_back(ev->fd, events[i].events, ev->arg);
- }
- if((events[i].events&EPOLLOUT)&&(ev->events&EPOLLOUT)) // write event
- {
- ev->call_back(ev->fd, events[i].events, ev->arg);
- }
- }
- }//while
- close(connfd);
- }
复制代码 |
|