好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Socket和数据库的一些使用---郭雪彬

sockaddr_in server_addr; pthread_mutex_t mut; struct kevent events[ 10 ];
  //  IP地址、端口和协议族 
    server_addr.sin_len =  sizeof ( struct   sockaddr_in);
    server_addr.sin_family  =  AF_INET;
    server_addr.sin_port  =  htons(SERVER_PORT);
    server_addr.sin_addr.s_addr  =  inet_addr(ipAddress);
    bzero( &(server_addr.sin_zero), 8 );
  //  创建socket 
     int  server_sock_fd = socket(AF_INET, SOCK_STREAM,  0  );
      if  (server_sock_fd == - 1  ) {
        perror(  "  socket error  "  );
          return   NULL;
    }
      int  on= 1  ;
      if ((setsockopt(server_sock_fd,SOL_SOCKET,SO_REUSEADDR,&on, sizeof (on)))< 0  )
    {
        perror(  "  setsockopt failed  "  );
        exit(EXIT_FAILURE);
    }
      //  绑定socket 
     int  bind_result = bind(server_sock_fd, ( struct  sockaddr *)&server_addr,  sizeof  (server_addr));
      if  (bind_result == - 1  ) {
        perror(  "  bind error  "  );
          return   NULL;
    }
    
    
      //监听 
     if  (listen(server_sock_fd, BACKLOG) == - 1  ) {
        perror(  "  listen error  "  );
          return   NULL;
    }
      struct  timespec timeout = { 10 , 0  };
      //  kqueue 
     int  kq =  kqueue();
      if  (kq == - 1  ) {
        perror(  "  创建kqueue出错!\n  "  );
        exit(  1  );
    } 
 struct   kevent event_change;
    EV_SET( &event_change, STDIN_FILENO, EVFILT_READ, EV_ADD,  0 ,  0  , NULL);
    kevent(kq,  &event_change,  1 , NULL,  0  , NULL);
    EV_SET( &event_change, server_sock_fd, EVFILT_READ, EV_ADD,  0 ,  0  , NULL);
    kevent(kq,  &event_change,  1 , NULL,  0  , NULL);
    
      while  ( 1  ) {

          int  ret = kevent(kq, NULL,  0 , events,  10 , & timeout);
          if  (ret <  0  ) {
            printf(  "  kevent 出错!\n  "  );
              continue  ;
        }  else   if (ret ==  0  ){
            printf(  "  kenvent 超时!\n  "  );
              continue  ;
        }  else  {
              //  ret > 0 返回事件放在events中 
             for  ( int  i =  0 ; i < ret; i++ ) {
                  struct  kevent current_event =  events[i];
                  //  kevent中的ident就是文件描述符 
                 if  (current_event.ident ==  STDIN_FILENO) {
                      //  标准输入 
                     bzero(input_msg, BUFFER_SIZE);
                    fgets(input_msg, BUFFER_SIZE, stdin);
                      //  输入 ".quit" 则退出服务器 
                     if  (strcmp(input_msg, QUIT_CMD) ==  0  ) {
                        exit(  0  );
                    }
                      for  ( int  i= 0 ; i<CONCURRENT_MAX; i++ ) {
                          if  (client_fds[i]!= 0  ) {
                            send(client_fds[i], input_msg, BUFFER_SIZE,   0  );
                        }
                    }
                }  else   if (current_event.ident ==  server_sock_fd){
                      //  有新的连接请求 
                     struct   sockaddr_in client_address;
                    socklen_t address_len;
                      int  client_socket_fd = accept(server_sock_fd, ( struct  sockaddr *)&client_address, & address_len);
                      if  (client_socket_fd >  0  ) {
                          int  index = - 1  ;
                          for  ( int  i =  0 ; i < CONCURRENT_MAX; i++ ) {
                              if  (client_fds[i] ==  0  ) {
                                index  =  i;
                                client_fds[i]  =  client_socket_fd;
                                  break  ;
                            }
                        }
                          if  (index >=  0  ) {
                            EV_SET( &event_change, client_socket_fd, EVFILT_READ, EV_ADD,  0 ,  0  , NULL);
                            kevent(kq,  &event_change,  1 , NULL,  0  , NULL);
                            printf(  "  新客户端(fd = %d)加入成功 %s:%d \n  "  ,client_socket_fd,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
                              /*  客户端赋值  */  
                            strcpy(client.ipAddress, inet_ntoa(client_address.sin_addr));
                            client.client_port  =  ntohs(client_address.sin_port);
                            client.client_ID  =  client_socket_fd;
                            
                              /*  收集客户端信息并且存储到列表中  */ 
 //                              if (AddClient(client, &clientList) == false) {
  //                                  fprintf(stderr, "Problem allcating memory\n");
  //                                  break;
  //                              }
  //                              if(ListIsFull(&clientList))
  //                              {
  //                                  puts("The list is now full.\n");
  //                                  break;
  //                              }
  //                              if(ListIsEmpty(&clientList))
  //                              {
  //                                  printf("NO client Connection");
  //                              }else
  //                              {
  //                                  Traverse(&clientList, showClients);
  //                              }
  //                              printf("在线客户端人数:%d\n", ListClientCount(&clientList)); 
                            
                            
                             if (!QueueIsFull(& line))
                            {
                                client.client_ID  =  client_socket_fd;
                                client.client_port  =  ntohs(client_address.sin_port);
                                strcpy(client.ipAddress, inet_ntoa(client_address.sin_addr));
                                EnQueue(client,  &line);  //  将客户端添加到队列中 
                                 char  msg[ 250  ];
                                  char  wellcome[ 250  ];
                                
                                sprintf(msg,  "  新客户端(fd = %d) 加入成功 %s:%d  "  ,client_socket_fd,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
                                
                                sprintf(wellcome,   "  WellComm To NB Socket Server System your fd is %d addr is %s and port is %d  "  ,client_socket_fd,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
                                
                                  //  给所有客户端发送消息,除了刚刚连接上的客户端之外 
                                 for ( int  i= 0 ; i<QueueItemCount(&line); i++ )
                                {
                                    
                                      if (index !=  i)
                                    {
                                        send(client_fds[i], msg, BUFFER_SIZE,   0  );
                                    }  else  
                                    {
                                        send(client_fds[i], wellcome, BUFFER_SIZE,   0  );
                                    }
                                }
                            }
                            
                        }  else  {
                            
                            bzero(input_msg, BUFFER_SIZE);
                            strcpy(input_msg,   "  服务器加入的客户端数达到最大值,无法加入!\n  "  );
                            send(client_socket_fd, input_msg, BUFFER_SIZE,   0  );
                            printf(  "  客户端连接数达到最大值,新客户端加入失败 %s:%d \n  "  ,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
                            
                        }
                    }
                }  else  {
                      //  处理某个客户端过来的消息 
                     bzero(recv_msg, BUFFER_SIZE);
                      long  byte_num = recv(( int )current_event.ident,recv_msg,BUFFER_SIZE, 0  );
                      if  (byte_num >  0  ) {
                          if  (byte_num >  BUFFER_SIZE) {
                            byte_num  =  BUFFER_SIZE;
                        }
                        recv_msg[byte_num]  =  ‘  \0  ‘  ;
                        printf(  "  客户端(fd = %d):%s\n  " ,( int  )current_event.ident,recv_msg);
                        
                          char  delims[] =  "   "  ;
                          char  *result =  NULL;

                        result  =  strtok(recv_msg, delims);
                          int  k =  0  ;
                          while ( result !=  NULL ) {
                              if (k== 0  )
                            {
                                strcpy(tableName, result);

                            }  else   if  (k ==  1  )
                            {
                                strcpy(userID, result);

                            }
                        
                            k ++ ;
                            printf(   "  result is \"%s\n  "  , result );
                            result  =  strtok( NULL, delims );
                        }
                            sendMessage(client_fds[  0 ], tableName, userID, user, & line);
                          break  ;
                    }  else   if (byte_num <  0  ){
                        printf(  "  从客户端(fd = %d)接受消息出错.\n  " ,( int  )current_event.ident);
                    }  else  {
                        EV_SET( &event_change, current_event.ident, EVFILT_READ, EV_DELETE,  0 ,  0  , NULL);
                        kevent(kq,  &event_change,  1 , NULL,  0  , NULL);
                        close((  int  )current_event.ident);
                          for  ( int  i =  0 ; i < CONCURRENT_MAX; i++ ) {
                              if  (client_fds[i] == ( int  )current_event.ident) {
                                
                                Client  *exitClient = (Client *) malloc ( sizeof  (Client));
                                
                                exitClient ->client_ID = ( int  )current_event.ident;
                                
  //                                  selectClientWithFds((int)current_event.ident, &line);
  //                                  int count = selectAllCilent(&line);  //  查找所有在线客户端
                                
  //                             bool   del =  deleteClientFormList(&clientList, *exitClient);
                                
  //                                  printf("%d\n",del);
                                
  //                                  Traverse(&clientList, showClients);
                                
  //                                  if(!ListIsEmpty(&clientList))
  //                                  {
  //                                      printf("\n排序后的元素\n");
  //                                      int desc = DescClientFromList(&clientList);
  //                                      Traverse(&clientList, showClients);
  //                                      printf("\n逆置后的元素\n");
  //                                      Reverse(&clientList);
  //                                      Traverse(&clientList, showClients);
  //                                  }

  //                                  printf("在线客户端人数:%d\n", ListClientCount(&clientList)); 
                                 
                                printf(  "  客户端(fd = %d)退出了\n  " ,( int  )current_event.ident);
  //                                  printf("剩余在线客户端个数%d\n",count); 
                                client_fds[i] =  0  ;
                                  break  ;
                            }
                        }
                    }
                }
            }
        }
        
    }      return   NULL;
   
}
  void   showClients(Client client)
{
  //      printf("客户端 IP: %s, port is %d, fds is %d\n",client.ipAddress, client.port, client.fds); 
 }
  //  void sendClientStates(int clientCount,Queue *pq)
  //  {
  //     
 //     
 //  }


  //  对接收到的服务端消息进行处理,并且进行回应 
 void  * sendMessage( int  client_fds,  char  * message,  char  *userID,  struct  userTableInfo *userInfo, Queue * pq)
{
      struct  userMessage user =  selectUserInfoWithUserID(message, userID);
    printf(  "  username is %s\n  "  , user.name);
    
    send(client_fds, user.name, BUFFER_SIZE,   0  );
    send(client_fds, user.user_id, BUFFER_SIZE,   0  );
    send(client_fds, user.birthday, BUFFER_SIZE,   0  );
    
    
  //      pthread_mutex_unlock(&mut); 
     return   NULL;
    
} 

以上是服务端部分代码,服务端将上线的客户端加入到链表中进行管理,当客户端上线时,服务端根据Socket的消息将客户端有关信息加入到链表中。

由于所有操作都在同一台计算机中,所以IP地址都是相同的

下面通过客户端对服务端发送相关指令获取对应的用户信息,该操作是基于客户端的指令,然后服务端通过相应指令对数据库进行查询,由于时间问题,目前该项目还不是很完善。

 

 由于代码都是基于C语言,可以在linux, mac, windows等环境运行。

待续。。。。

 

Socket和数据库的一些使用---郭雪彬

标签:

查看更多关于Socket和数据库的一些使用---郭雪彬的详细内容...

  阅读:22次