2017-04-17 138 views
1

我正嘗試創建一個簡單的tcp服務器客戶端。如果客戶端向服務器發送數據,但是當服務器嘗試回答整個連接掛起時,我的程序工作正常。我正在使用write()/ read()函數。客戶端嘗試從服務器tcp回讀時掛起

Server代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <stdbool.h> 

#define SIZE 700000000 


/////////////////////////////////////////////////////////////////////////// 


int main(int argc, char *argv[]) { 


    int sockfd, newsockfd, portno, clilen; 
    char buffer[256]; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 


    /* First call to socket() function */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    if (sockfd < 0) { 
    perror("ERROR opening socket"); 
    exit(1); 
    } 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    portno = 5001; 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(portno); 



    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 
    perror("ERROR on binding"); 
    exit(1); 
    } 

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

    /* Accept actual connection from the client */ 
    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); 

    if (newsockfd < 0) { 
    perror("ERROR on accept"); 
    exit(1); 
    } 


    bzero(buffer, 255); 

    int readbyte = 0; 

    do { 

    readbyte = read(newsockfd, buffer, 1024); 

    if (readbyte < 0) 
    { 
     perror("ERROR on reading socket!"); 
     break; 
    } 
    if (readbyte > 0) 
    { 
     //printf("Here is the message: %s\n",buffer); 
    } 


    } while (readbyte > 0); /* until EOF */ 



    int writen = write(newsockfd, "I received your message", strlen("I received your message") + 1); 

    if (writen<0){ 
    perror("Error"); 
    } 

    //debug(); 

    return 0; 
} 

客戶端代碼:

#include <stdio.h> 
#include <stdlib.h> 

#include <netdb.h> 
#include <netinet/in.h> 

#include <string.h> 

////////////////////////////////////////////////////////////////// 


int main(int argc, char *argv[]) { 

    int sockfd, portno, n; 
    struct sockaddr_in serv_addr; 
    struct hostent *server; 
    int mode; 
    char *code; 
    char buffer[256]; 
    char *uptr = buffer; 
    int i; 




    if (argc < 3) { 
    fprintf(stderr, "Use: %s [hostname] [port] [args]\n", argv[1]); 
    exit(0); 
    } 

    portno = atoi(argv[2]); 


    /* Create a socket point */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    if (sockfd < 0) { 
    perror("ERROR opening socket"); 
    exit(1); 
    } 

    server = gethostbyname(argv[1]); 

    if (server == NULL) { 
    fprintf(stderr, "ERROR, no such host\n"); 
    exit(0); 
    } 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); 
    serv_addr.sin_port = htons(portno); 

    int sock_et = connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr); 

    /* Now connect to the server */ 
    if (sock_et < 0) { 
    perror("ERROR connecting"); 
    exit(1); 
    } 
/* some code... */ 

while (len > 0) { 

    int writen = write(sockfd, buf, len + 1); 

    if (writen < 0) 
    { 
     printf("Error writting to socket!\n"); 
     break; 
    } 

    len -= writen; 
    buf += writen; /* tricky pointer arythmetic */ 

    } 

printf("Finished writing to server\n"); 
    bzero(buffer, 256); 
    int readbyte; 

do { 

    readbyte = read(sock_et, buffer, 1024); 

    if (readbyte < 0) 
    { 
     perror("ERROR on reading socket!"); 
     break; 
    } 
    if (readbyte > 0) 
    { 
     //printf("Here is the message: %s\n",buffer); 
    } 


    } while (readbyte > 0); /* until EOF */ 

    printf("%s\n",buffer); 




    close(sockfd); 


    return 0; 
} 

任何幫助,將不勝感激!謝謝!

+0

在服務器和客戶端中,您都有一個256字節的緩衝區,但是您告訴'read'它可以將1024個字節讀入該緩衝區。什麼遲早會導致緩衝區溢出和*未定義的行爲*並可能真的發生壞事。 –

+0

你是對的沒有注意到!非常感謝:) –

+0

@Someprogrammerdude我改變了它,但仍然掛起 –

回答

0
  1. 您的客戶端代碼不編譯
  2. 你永遠不會從閱讀得到一個0(EOF),而插座是開放的(無論是在客戶端或服務器) - 所以只需添加一個break後現在成功閱讀。
  3. 您還沒有關閉套接字服務器
  4. 在客戶端,你需要從sockfd閱讀,不sock_et

可能有其他問題。它看起來像你試圖從這裏使用client.c/server.c:http://www.linuxhowtos.org/C_C++/socket.htm

如果我使用這些文件,它工作正常。因此,從他們開始,並更仔細地應用您的更改。