2015-04-26 2 views
-1

Я пытаюсь связаться с сервером (SENSORSERVER) и клиентом (CGI) с помощью функции send(). Первый цикл вокруг SENSORSERVER корректно отправляет строку «Hello world» в CGI, но во втором цикле вокруг цикла while CGI не получает должным образом функцию recv.C функция отправки между сервером и клиентом не работает

SENSORSERVER Код

int main() { 

    pthread_mutex_init(&mutex, NULL); 

    int welcomeSocket, newSocket; 
    char buffer[1024]; 
    struct sockaddr_in serverAddr; 
    struct sockaddr_storage serverStorage; 
    socklen_t addr_size; 

    //pthread_create(&t0, NULL ,background(),(void *)""); 
    //pthread_detach(t0); 

    //int pthread_join(); 
    pid = fork(); 

    if(pid == -1){ 
     printf("failed to fork"); 
    } 

    if(pid == 0){ 

     pthread_create(&t0, NULL, background(), (void*)""); 
     pthread_detach(t0); 

    } else { 


      /*---- Create the socket. The three arguments are: ----*/ 
      /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */ 
      while(1){ 

      welcomeSocket = socket(PF_INET, SOCK_STREAM, 0); 

      /*---- Configure settings of the server address struct ----*/ 
      /* Address family = Internet */ 
      serverAddr.sin_family = AF_INET; 
      /* Set port number, using htons function to use proper byte order */ 
      serverAddr.sin_port = htons(7891); 
      /* Set IP address to localhost */ 
      serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
      /* Set all bits of the padding field to 0 */ 
      memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 



      /*---- Bind the address struct to the socket ----*/ 
      bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); 

      /*---- Listen on the socket, with 5 max connection requests queued ----*/ 
      if(listen(welcomeSocket, 0) == 0) 
      printf("Listening\n"); 
      else 
      printf("Error\n"); 



      /*---- Accept call creates a new socket for the incoming connection ----*/ 
      addr_size = sizeof serverStorage; 
      newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 

      /*---- Send message to the socket of the incoming connection ----*/ 

      int er = pthread_mutex_trylock(&mutex); 


      if (er == 0) 
      { 




      strcpy(buffer,"Hello World\n"); 



      send(newSocket, buffer, sizeof(buffer), 0); 


       close(newSocket); 
       close(welcomeSocket); 


       pthread_mutex_unlock(&mutex); 


      } 


    } 
    } 
return EXIT_SUCCESS; 
} 

И код CGI клиента

char buf[1024]; 
char buf2[2024]; 




int main(void) { 

    int clientSocket; 
    char buffer[1024]; 
    struct sockaddr_in serverAddr; 
    socklen_t addr_size; 

    /*---- Create the socket. The three arguments are: ----*/ 
    /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */ 
    clientSocket = socket(PF_INET, SOCK_STREAM, 0); 
    /*---- Configure settings of the server address struct ----*/ 
    /* Address family = Internet */ 
    serverAddr.sin_family = AF_INET; 
    /* Set port number, using htons function to use proper byte order */ 
    serverAddr.sin_port = htons(7891); 
    /* Set IP address to localhost */ 
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    /* Set all bits of the padding field to 0 */ 
    memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 

    /*---- Connect the socket to the server using the address struct ----*/ 
    addr_size = sizeof serverAddr; 
    connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); 

    /*---- Read the message from the server into the buffer ----*/ 
    int er; 
    er = recv(clientSocket, buffer, sizeof(buffer), 0); 



    /*---- Print the received message ----*/ 
    printf("Data received: %s",buffer); 
    //close(clientSocket); 



    puts("<p>Hello <b>CGI</b</p>"); 
    puts("</BODY>"); 
    puts("</HTML>"); 


    return EXIT_SUCCESS; 
    } 

SENSORSERVER получит функции принимают(), а затем, когда CGI получает прием он будет продолжать и продолжать и все кажется прекрасным. Однако мне нужно, чтобы CGI мог быть вызван снова и снова, пока работает SENSORSERVER, и чтобы сервер отправил клиенту сообщение. Он отправляет его только один раз!

Первый цикл круглый выход -

Data received: Hello World 
<p>Hello <b>CGI</b</p> 
</BODY> 
</HTML> 
logout 

Второй контур круглый -

Data received: 
<p>Hello <b>CGI</b</p> 
</BODY> 
</HTML> 
logout 

Может кто-нибудь увидеть, где проблема?

ответ

1

Проблема заключается в том, что ваш сервер принимает только одно соединение (единственный звонок accept), а затем после отправки сообщения, которое он выдает. Таким образом, второй запуск клиента приведет к сбою соединения (больше нет прослушивания в сокете) и напечатайте пустое сообщение (при игнорировании кода ошибки).

Если вы хотите, чтобы сервер мог обрабатывать несколько соединений, вам необходимо иметь вызов accept в цикле. Как именно вы хотите это сделать, зависит от того, как вы хотите обрабатывать соединения. Самым простым было бы отправить сообщение, закрыть принимающем соединения, и петля:

while (1) { /* infinite loop */ 
    /*---- Accept call creates a new socket for the incoming connection ----*/ 
    addr_size = sizeof serverStorage; 
    newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 
    if (newSocket < 0) { 
     perror("accept"); 
     break; } 
    /*---- Send message to the socket of the incoming connection ----*/ 
    int er = pthread_mutex_trylock(&mutex); 
    if (er == 0) { 
     strcpy(buffer,"Hello World\n"); 
     send(newSocket, buffer, sizeof(buffer), 0); 
     close(newSocket); 
     pthread_mutex_unlock(&mutex); 
    } else { 
     /* mutex lock failed (busy?) -- need to do something */ 
     strcpy(buffer,"Error occurred\n"); 
     send(newSocket, buffer, sizeof(buffer), 0); 
     close(newSocket); 
    } 
} 
close(welcomeSocket); 

Если вы хотите сделать что-нибудь более сложное с входящего соединения, вы можете раскошелиться процесс или нить, чтобы справиться с этим, вместо того, чтобы делать это непосредственно в цикле, поскольку второе соединение не может быть принято до тех пор, пока не будет обработано первое, и цикл вернется к вызову accept.

Смежные вопросы