2014-01-30 85 views
0

我有一個簡單的基於tcp的客戶端和c服務器編寫的服務器,但是一旦我建立連接後服務器發送消息回到客戶端,連接停止工作。你能幫我解決這個問題 - 我希望服務器繼續接收/發送消息給客戶端。C中的客戶端和服務器如何保持通信

代碼:

Server.c

#include <stdio.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include <arpa/inet.h> 
#include <errno.h> 
#include <string.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <fcntl.h> 
#include <unistd.h> 

#define port 5000 
#define buf  512 

void answer(int); 

int main(int argc, char *argv[]){ 
    int sock = socket(AF_INET, SOCK_STREAM, 0); 
    int portid; 
    int backlog = 10; 
    struct sockaddr_in addr; 
    char BUFF[buf]; 
    int n; 
    int received = 0; 
    int connfd; 

    if(sock == -1){ 
     perror("socket error"); 
     exit(errno); 
    } 

    memset(&addr,0, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = INADDR_ANY; 

    if(bind(sock, (struct sockaddr*) &addr, sizeof(addr)) == -1){ 
      perror("bind error"); 
      exit(errno); 
    } 

    if(listen(sock, backlog) == -1){ 
      perror("listen error"); 
      exit(errno); 
    } 

    listen(sock, 5); 
    struct sockaddr_in cliaddr; 
    //struct sockaddr_in addr; 
    int cliaddr_len = sizeof(cliaddr); 

    while(1){ 

     connfd = accept(sock, (struct sockaddr*)&cliaddr,&cliaddr_len); 
     if(connfd == -1){ 
      perror("error connfd"); 
      exit(errno); 
     } 
     portid = fork(); 
     if(portid<0) 
      perror("error on fork"); 
     if(portid ==0){ 
      close(sock); 
      answer(connfd); 
      exit(0); 
     } 


     //close(sock); 
    } 

    close(connfd); 
    return 0; 

    //close(sock); 
    //return 0; 
} 

void answer(int connfd){ 
    int n; 
    char BUFF[buf]; 
    memset(BUFF,buf,buf); 
    n = read(connfd,BUFF,buf); 
    printf("connected: %s",BUFF); 
    //received = 1; 
    //memset(BUFF,0,buf); 
    printf("please enter your message: "); 
    memset(BUFF,0,buf); 
    fgets(BUFF,buf, stdin); 
    n = write(connfd, BUFF,strlen(BUFF)); 
    if(n<0) err("writing to socket problem"); 
} 

回答

1

您的服務器調用fork,然後if(portid ==0){...get and send message...},然後將其返回到它試圖accept()循環的頂部--- 孩子的工作,但孩子正在努力做到這一點。

重構你的代碼來做你想做的事。將其分解成更小的部分,這些部分對於您來說很簡單,因此您可以看到類似的東西。

+0

改變它,但我仍然沒有進展我錯了 –

+0

你移動代碼,但你沒有改變它。你描述了一旦建立連接,你希望服務器_loop_,但是你沒有寫一個循環來做到這一點。從你的重構中,在'answer()'函數中放置一個循環將是合適的。 – mah

+0

是的,我的問題是我沒有循環發送/接收代碼 –

0

這是因爲您的recv()數據只是一次。使用一個循環來接收,直到客戶端斷開連接。

while ((n = read(connfd,BUFF,buf)) 
    { 
     printf("connected: %s",BUFF); 
     //received = 1; 
     //memset(BUFF,0,buf); 
     printf("please enter your message: "); 
     memset(BUFF,0,buf); 
     fgets(BUFF,buf, stdin); 
     n = write(connfd, BUFF,strlen(BUFF)); 
     if(n<0) err("writing to socket problem"); 
    } 
0

您正在閱讀你的孩子的資料,所以一旦孩子完成退出程序,所以嘗試在父閱讀並沿送孩子中的數據。

+0

父母每個連接只發送一次數據,所以孩子做什麼並不重要。這就是說,孩子有一個循環,它讀取和寫入,直到任何'err()'調用導致它退出。帖子編輯刪除了客戶端代碼,但您可以通過http://stackoverflow.com/posts/21456178/revisions查看它以查看此信息。 – mah