2017-04-17 141 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

如果我使用这些文件,它工作正常。因此,从他们开始,并更仔细地应用您的更改。