2012-10-14 63 views
0

我試圖開發C中的應用程序接收消息並在TCP發送線程在TCP客戶機/服務器。爲此,我使用了2個線程:要監聽的服務器線程和客戶端線程發送它。字符串在C

這裏的服務器和主要功能:

void dostuff(int sock) 
{ 
    int n; 
    char buffer[256]; 

    bzero(buffer,256); 
    n = read(sock,buffer,255); 

    if (n < 0) error("ERROR reading from socket"); 
    else { 
    pthread_t t_tcp_client; 
    pthread_create(&t_tcp_client, NULL, tcp_client, buffer); 
    } 

    n = write(sock,"Message received",18); 

    if (n < 0) error("ERROR writing to socket"); 
} 

static void *tcp_server(void *p_data) 
{ 
    int sockfd, newsockfd, pid; 
    socklen_t clilen; 
    struct sockaddr_in serv_addr, cli_addr; 

    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    if (sockfd < 0) error("ERROR opening socket"); 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(TCP_PORT); 

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); 

    listen(sockfd,5); 
    clilen = sizeof(cli_addr); 

    while (1) { 
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 

    if (newsockfd < 0) error("ERROR on accept"); 

    pid = fork(); 

    if (pid < 0) error("ERROR on fork"); 

    if (pid == 0) { 
     close(sockfd); 
     dostuff(newsockfd); 
     exit(0); 
    } else { 
     close(newsockfd); 
    } 
    } 
    close(sockfd); 
    return 0; 
} 


int main (void) 
{ 
    pthread_t t_tcp_server; 
    pthread_create(&t_tcp_server, NULL, tcp_server, NULL); 

    pthread_join(t_tcp_server, NULL); 

    return 0; 
} 

而且客戶端線程:

static void *tcp_client(void *p_data) 
{ 
    if (p_data != NULL) 
    { 
    char const *message = p_data; 

    printf("Message transmitted : %s\n", message); 
    } 

    return 0; 
} 

的問題是,客戶端線程不會收到良好的焦炭,其結果是:

傳送的消息:???〜?

我認爲問題來自於行:N =讀(襪子,緩衝液,255);但我不明白爲什麼。

謝謝您的幫助

回答

1
static char buffer[256]; 

void dostuff(int sock) 
{ 
    int n; 

    bzero(buffer,256); 
    n = read(sock,buffer,255); 
    ... 
} 

使用套接字時要小心,一次讀取可能不會給出您等待的消息的總數。

在結構化消息的情況下,你定義的協議(你應該定義它)必須先給出一個消息標識符,然後你閱讀,直到你收到sizeof(theSpecificMessage)爲止,這個特定消息由標識符標識。

+0

謝謝你和alk的幫助,它工作正常;) – skurty

1

do_stuff最有可能之前客戶線程做了它的工作退出。

客戶端線程使用,然後當do_stuff退出已被釋放,並會通過一些其他的代碼被重用堆棧分配的內存。

對此的解決方案將是堆分配的存儲器傳遞到客戶端。如果動態分配,後者需要在客戶端完成工作後才能被釋放。

+0

1是的,炭緩衝液[256]將在堆棧上被分配,當dostuff()返回時,它會被堆疊的另一使用改變。在靜態外部dostuff()聲明它。 – Aubin

+0

你同意,不是嗎? @Aubin – alk

+0

是的,它似乎是正確的。 – Aubin