不能在一对UNIX套接字客户端服务器之间交换消息以仅rand

时间:2019-07-11 18:12:25

标签: c linux sockets process pthreads

我正在尝试在一对客户端和服务器之间建立unix套接字通信,其中客户端和服务器将是在同一台计算机上运行的两个不同进程,并且客户端将从命令行接收输入,并将其传递给服务器,并且服务器将然后用缓冲区响应。两者都应该能够以两种方式随机通信。为此,我在两端打开了套接字,并在无限循环中等待从另一端接收。但是,在客户端,一旦我开始在无限循环中等待recv,就无法向服务器发送命令行指令,则总是在循环中受阻。如果我先向服务器发送命令行指令,则无法从服务器接收任何内容。在服务器上也是如此。我使用select()调用实现了,但是它还在无限循环中等待以获取FD_SET和recv,因此再次陷入了同样的境地。我还尝试过在客户端发送和接收消息时使用不同的线程,但是由于它总是在无限循环中等待,因此我再次陷入了recv中。谁能建议实现这一目标的有效机制。

Code snippet is as below:

#####################################################CLIENT######################################
void* msimcli_RecvFromSocket(void *)                                                                                    
{                                                                                                                       
   int msglength = 0;                                                                                                   
   int result = 0;                                                                                                      
   char buffer[CLI_MAX_BUF_SIZE];                                                                                       
   pthread_setname_np(pthread_self(), "CliRcThd");                                                                      

   printf("\nWait in Rx on socket descriptor %d\n",datagramSocket.fd);                                                  
   do{                                                                                                                  
      result = select(datagramSocket.fd + 1, &datagramSocket.rset, NULL, NULL, NULL);                                   
   }while(result == -1 && errno == EINTR);                                                                              

   if (result > 0){                                                                                                     
      if (FD_ISSET(datagramSocket.fd, &datagramSocket.rset))                                                            
      {                                                                                                                 
         printf("FD SET Rx on socket descriptor %d\n",datagramSocket.fd);                                               
         /* The socket_fd has data available to be read */                                                              
         msglength = recv(datagramSocket.fd, buffer, CLI_MAX_BUF_SIZE, 0);                                              
         if (msglength == 0) {                                                                                          
            /* This means the other side closed the socket */                
             close(datagramSocket.fd);                                                                                   
         }                                                                                                              
         else if(msglength > 0){                                                                                        
            printf("Message received at cli\n");                                                                        
            printf("Rcvd string = %s\n",(char*)buffer);                                                                 
            /* TBD */                                                                                                   
            //return 1;                                                                                                 
         }                                                                                                              
      }                                                                                                                 
   }                                                                                                                    
   else if (result < 0)                                                                                                 
   {                                                                                                                    
      /* An error ocurred, just print it to stdout */                                                                   
      printf("Error on select(): %s\n", strerror(errno));                                                               
   }                                                                                                                    
}               

int msimcli_SendToSocket(void* buf)                                                                                     
{                                                                                                                       
   int rc = ROK;                                                                                                        
   /*Test buffer*/                                                                                                      
   cliCmd *buff = (cliCmd *)buf;                                                                                        
   printf("Buff %s\n", ((cliCmd *)buf)->buf);                                                                           
   for (int i = 0; i < buff->hdr.msglen; i++)                                                                           
   {                                                                                                                    
    printf("[%x]", buff[i]);                                                                                            
   }                                                                                                                    
   printf("\n");                                                                                                        
   printf("sending on socket [%d]\n",datagramSocket.fd);                                                                
   rc = sendto(datagramSocket.fd, buf, buff->hdr.msglen, 0, (struct sockaddr *)&datagramSocket.remote, datagramSocket.len);
   if (rc == -1) {                                                                                                      
      printf("%s: errno=0x%x %s\r\n", __FUNCTION__,errno, strerror(errno));                                             
      printf("SENDTO ERROR\n");            close(datagramSocket.fd);                                                                                         
      return 0;                                                                                                         
      //exit(1);                                                                                                          
   }                                                                                                                    
   else {                                                                                                               
      printf("Data sent!\n");                                                                                           
      return rc;                                                                                                        
   }                                                                                                                    
}
int msimcli_ConnectToSocket(const char* socketFile,int isSockTypeStreaming,SOCKET_PARAMS* socketParam)
{                                                                                                                       
   int rc = ROK;                                                                                                        
   int result = 0;                                                                                                      
   char      buffer[CLI_MAX_BUF_SIZE];                                                                                  
   int       buffer_size = CLI_MAX_BUF_SIZE;                                                                            
   socklen_t len;                                                                                                       
   MSIM_ZERO(*socketParam);                                                                                             
   pthread_t snd_tid;                                                                                                   
   pthread_t rx_tid;                                                                                                    

   if (isSockTypeStreaming)                                                                                             
   {                                                                                                                    
      socketParam->type = SOCK_STREAM;                                                                                  
   }                                                                                                                    
   else                                                                                                                 
   {                                                                                                                    
      socketParam->type = SOCK_DGRAM;                                                                                   
   }
   socketParam->fd = socket(AF_UNIX, socketParam->type, 0);                                                             
   if (0 > socketParam->fd)                                                                                             
   {                                                                                                                    
      rc = RFAILED;                                                                                                     
      goto Exit;                                                                                                        
   }                                                                                                                    
   else                                                                                                                 
   {                                                                                                                    
      printf("socket created successfully with socket descriptor %d\n",socketParam->fd);                                
   }                                                                                                                    
   socketParam->remote.sun_family = AF_UNIX;                                                                            
   strcpy(socketParam->remote.sun_path, socketFile);
   socketParam->len = strlen(socketParam->remote.sun_path) + sizeof(socketParam->remote.sun_family) + 1;
   FD_ZERO(&socketParam->rset);                                                                                         
   FD_SET(socketParam->fd, &socketParam->rset);
   /* Create Receiver thread */                                                                                         
   if(ROK != (rc = pthread_create(&rx_tid,NULL,msimcli_RecvFromSocket,NULL)))                                           
   {                                                                                                                    
       printf("Thread create for Receiver failed\n");                                                                   
       goto Exit;                                                                                                       
   }
Exit:
   if (ROK != rc)    {                                                                                                                    
      printf("%s: errno=0x%x %s\r\n", __FUNCTION__,errno, strerror(errno));                                             
      if (-1 < socketParam->fd)                                                                                         
      {                                                                                                                 
         close(socketParam->fd);                                                                                        
         socketParam->fd = -1;                                                                                          
      }                                                                                                                 
   }
   printf("<< rc %d\r\n", rc);                                                                                          
   return rc;                                                                                                           
}

int msimcli_ConnectToSocket(const char* socketFile,int isSockTypeStreaming,SOCKET_PARAMS*  socketParam)
{                                                                                                                       
   int rc = ROK;                                                                                                        
   int result = 0;                                                                                                      
   char      buffer[CLI_MAX_BUF_SIZE];                                                                                  
   int       buffer_size = CLI_MAX_BUF_SIZE;                                                                            
   socklen_t len;                                                                                                       
   MSIM_ZERO(*socketParam);                                                                                             
   pthread_t snd_tid;                                                                                                   
   pthread_t rx_tid;                                                                                                    

   if (isSockTypeStreaming)                                                                                             
   {                                                                                                                    
      socketParam->type = SOCK_STREAM;                                                                                  
   }                                                                                                                    
   else                                                                                                                 
   {                                                                                                                    
      socketParam->type = SOCK_DGRAM;                                                                                   
   }
   socketParam->fd = socket(AF_UNIX, socketParam->type, 0);                                                             
   if (0 > socketParam->fd)                                                                                             
   {                                                                                                                    
      rc = RFAILED;                                                                                                     
      goto Exit;                                                                                                        
   }                                                                                                                    
   else                                                                                                                 
   {                                                                                                                    
      printf("socket created successfully with socket descriptor %d\n",socketParam->fd);                                
   }                                                                                                                    
   socketParam->remote.sun_family = AF_UNIX;                                                                            
   strcpy(socketParam->remote.sun_path, socketFile);
   socketParam->len = strlen(socketParam->remote.sun_path) + sizeof(socketParam->remote.sun_family) + 1;             
   FD_ZERO(&socketParam->rset);                                                                                         
   FD_SET(socketParam->fd, &socketParam->rset);
   /* Create Receiver thread */                                                                                         
   if(ROK != (rc = pthread_create(&rx_tid,NULL,msimcli_RecvFromSocket,NULL)))                                           
   {                                                                                                                    
       printf("Thread create for Receiver failed\n");                                                                   
       goto Exit;                                                                                                       
   }                                                                                                               
Exit:
   if (ROK != rc){
      printf("%s: errno=0x%x %s\r\n", __FUNCTION__,errno, strerror(errno));                                             
      if (-1 < socketParam->fd)                                                                                         
      {                                                                                                                 
         close(socketParam->fd);                                                                                        
         socketParam->fd = -1;                                                                                          
      }                                                                                                                 
   }
   printf("<< rc %d\r\n", rc);                                                                                          
   return rc;
}

##########################################SERVER##########################################

       while(1)                                                                                                             
       {
          do{
             FD_ZERO(&rset);
             FD_SET(serverDatagramSocket, &rset);
             result = select(serverDatagramSocket + 1, &rset, NULL, NULL, NULL);
          } while (result == -1 && errno == EINTR);
          if (result > 0) {
             if (FD_ISSET(serverDatagramSocket, &rset)) {
                /* The socket_fd has data available to be read */
                msgLength = recv(serverDatagramSocket,buffer,CLI_MAX_BUF_SIZE, 0);
                if (msgLength == 0) {
                   printf("MsgLength zero, other side closed the socket\n");
                   /* This means the other side closed the socket */
                   close(serverDatagramSocket);
                }
                else if (msgLength > 0){
                   printf("MsgLength nonzero, message received on socket[%d]\n",serverDatagramSocket);
                   recvdCli.hdr.msglen = ((cliCmd *)buffer)->hdr.msglen;
                   recvdCli.hdr.msgtype = ((cliCmd *)buffer)->hdr.msgtype;
                   uint16_t buff_len = (recvdCli.hdr.msglen - sizeof(recvdCli.hdr));
                   strncpy((char *)recvdCli.buf, (char *)((cliCmd *)buffer)->buf, buff_len);
                   recvdCli.buf[buff_len] = '\0';
                   printf("hdr length : %d\n", recvdCli.hdr.msglen);
                   printf("hdr msgtype : %d\n", recvdCli.hdr.msgtype);
                   printf("buffer length : %d\n", buff_len);
                   printf("buffer : %s\n", recvdCli.buf);
                   /* Test send */
                   //FD_CLR(serverDatagramSocket,&rset);
                   macsim_SendDatagram((void*)str);
                   //return 1;
                }
             }
          }
          else if (result < 0) {
             /* An error ocurred, just print it to stdout */ 
                printf("Error on select():%s\n",strerror(errno));
       else if (result < 0) {
          /* An error ocurred, just print it to stdout */
          printf("Error on select(): %s\n", strerror(errno)); 
       }
    Exit:
       if (NULL != buffer)
       {                                                                                                                    
          free(buffer);                                                                                                     
       }                                                                                                                    
       if (-1 != serverDatagramSocket)                                                                                      
       {                                                                                                                    
          close(serverDatagramSocket);                                                                                      
          serverDatagramSocket = 1;                                                                                         
       }                                                                                                                    
       printf("<<rc = %d\r\n", rc);                                                                                         
       return rc;                                                                 
    }          

    int macsim_SendDatagram(void *buffer)                                                                                   
    {                                                                                                                       
       int rc = ROK;                                                                                                        
       /*Test buffer*/                                                                                                      

       printf("MACSIM Test Buffer is %s\n", (char*)buffer);                                                                 
       printf("\n");                                                                                                        

       printf("Trying to send on socket descripor [%d]\n",macsimDatagramSocket.fd);                                       
       rc = sendto(macsimDatagramSocket.fd, buffer, strlen((char*)buffer), 0, \                                             
             (struct sockaddr *)&macsimDatagramSocket.remote, macsimDatagramSocket.len);                                    
       if (rc == -1) {                                                                                                      
          printf("%s: errno=0x%x %s\r\n", __FUNCTION__,errno, strerror(errno));                                             
          printf("SENDTO ERROR\n");                                                                                         
          close(macsimDatagramSocket.fd);                                                                                   
          return 0;                                                                                        
       }                                                                                                                    
       else {                                                                                                               
          printf("Data sent!\n");                                                                                           
          return rc;                                                                                                        
       }                                                                                                                    
    }     



**Ouputs as follow:**

***Output at server:***
--------------------------------------------------------------
/*************************************************/
Open server socket
>>
>> socketFile=/dev/shm/sockets/logClient
Got opened with sock[6]
<< sock 6
Serever socket created with fd = 6
--------------------------------------------------
MsgLength nonzero, message received on socket[6]
hdr length : 13
hdr msgtype : 0
buffer length : 5
buffer : test1
MACSIM Test Buffer is TC Rcvd

Trying to send on socket descripor [6]
macsim_SendDatagram: errno=0x6b Transport endpoint is not connected
SENDTO ERROR


***Output at client:***

root@adkumar:/home/adkumar/git/5G_DU/src/macsim/bin# ./cli 
Start cli
socket created successfully with socket descriptor 3
<< rc 0

*********************************
                MENU               
***********************************
    1)runtest()                    
    1)stoptest()                    
    2)rerunlasttest()               
    0)exit()                         
Enter option from above menu:
Wait in Rx on socket descriptor 3
1
Enter TC to run
test1
Buff : test1
sending on socket [3]
Data sent!

*********************************
                MENU               
***********************************
    1)runtest()                    
    1)stoptest()                    
    2)rerunlasttest()               
    0)exit()                         
Enter option from above menu:1
Enter TC to run
test2
Buff : test2
sending on socket [3]
msimcli_SendToSocket: errno=0x6f Connection refused
SENDTO ERROR

0 个答案:

没有答案