2013-03-22 55 views
0

我需要向客戶端發送消息,然後客戶端必須使用選項做出響應。直到客戶端和服務器連接,但兩個程序都以「分段錯誤」結束。有誰知道這個錯誤是什麼意思?有人可以提供一個想法來了解如何創建一個可以使客戶端和服務器進行交互的代碼。在接收到客戶選擇的選項後,服務器必須分析它並將結果再次發送給客戶端。嘗試從服務器向客戶端發送消息的分段故障

我的代碼是:

服務器

int 
main(int argc, char **argv) 
{ 
    int     listenfd, connfd; 
    socklen_t   len; 
    struct sockaddr_in servaddr, cliaddr; 
    char    buff[MAXLINE]; 
    time_t    ticks; 
    char    message[MAXLINE]="This is the server"; 
    char    temp_scale[2]; 
    char    recvdata[MAXLINE + 1]; 

    listenfd = Socket(AF_INET, SOCK_STREAM, 0); 
    bzero(&servaddr, sizeof(servaddr)); 
    servaddr.sin_family  = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/ 
    servaddr.sin_port  = htons(5555); 

    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); 
    Listen(listenfd, LISTENQ); 

    for (; ;) 
    { 
     len = sizeof(cliaddr); 
     connfd = Accept(listenfd, (SA *) &cliaddr, &len); 

     printf("Connection from %s, port %d\n", 
       Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), 
       ntohs(cliaddr.sin_port)); 


     snprintf(message, sizeof(message), "%s\r\n"); 
      Writen(connfd, message, strlen(message)); 
      while ((n = read(connfd, recvdata, MAXLINE)) > 0) 
      { 
      recvdata[n] = 0; /* null terminate*/ 
      if (fputs(recvdata, stdout) == EOF) 
       err_sys("fputs error"); 
      } 
      if (n < 0) 
      err_sys("read error"); 

      Close(connfd); 
    } 
} 

客戶

int 
main(int argc, char **argv) 
{ 
    int     sockfd, rd; 
    socklen_t   len; 
    char    recvline[MAXLINE + 1]; 
    struct sockaddr_in servaddr, cliaddr; 
    char scale[2]; 

    /*if (argc != 2) 
     err_quit("usage: a.out <IPaddress>");*/ 

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
     err_sys("socket error"); 

    bzero(&servaddr, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_port = htons(atoi(argv[2])); /*port passed through command line*/ 
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) /*The client translates the server address, passed on the command line*/ 
     err_quit("inet_pton error for %s", argv[1]); 


    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) 
     err_sys("connect error"); 

    len = sizeof(cliaddr); 
    Getsockname(sockfd, (SA *) &cliaddr, &len); 
    printf("Local Address is: %s\n", 
      Sock_ntop((SA *) &cliaddr, sizeof(cliaddr))); 

    printf("Iniciando read...\n"); 
    while ((rd = read(sockfd, recvline, MAXLINE)) > 0) 
    { 
     recvline[rd] = 0; /* null terminate*/ 
     if (fputs(recvline, stdout) == EOF) 
      err_sys("fputs error"); 
    } 
    if (rd < 0) 
    err_sys("read error"); 

    printf("Enter option 'A' or 'B'"); 
    send_scale(sockfd); 

    exit(0); 
} 

感謝

+0

分段錯誤意味着您正在訪問禁止的內存,即您有一個與無效或指針或數組越界訪問相關的錯誤。 – Lundin 2013-03-22 07:24:51

+0

任何特定的原因,一些緩衝區的長度MAXLINE,但有一些MAXLINE + 1?如果不理解代碼,這就像臭蟲一樣。 – Lundin 2013-03-22 07:26:14

+0

謝謝,所以我可以知道如何解決這個問題?我在客戶端和服務器上使用相同的功能,這是否會造成問題? – netfreak 2013-03-22 07:27:00

回答

2

你的服務器可能出錯的,因爲這樣的:

snprintf(message, sizeof(message), "%s\r\n"); // <== no parameters 

這是完全錯誤。 snprintf()調用的格式說明符預期char *爲空終止的字符串,並且您絕對不會傳遞它。因此,它從棧中抓取一個隨機值,將其視爲指針,並將其解引用以嘗試完成格式化的請求。不知道你正在使用的API的細節(顯然它不是標準的BSD套接字,僅僅是名字),沒有太多的事情可以繼續下去。

+0

謝謝WhozCraig!就是這樣,我有一個字符串,並工作!現在我是閱讀部分的結構體,我將消息從服​​務器發送到客戶端,但客戶端不接收它。客戶端和服務器都處於阻塞讀取狀態(服務器期望客戶端的答案)。你知道它發生了什麼嗎? – netfreak 2013-03-23 04:26:11

+0

@netfreak我不知道,但我會盯上一段時間,看看它是否跳到我身上。我不是一個套接字的人,但是這個網站上有很多,所以也許會有人插入。 – WhozCraig 2013-03-23 05:48:45

2

在調試器(例如gdb ./a.out)運行你的代碼,並找出在任何時間。

0

我不知道這是否會幫助,但在C字符串的空終止「\ 0」,當你打印你的迴應:

recvdata[n] = 0; /* null terminate ----> this must be '\0'*/ 
if (fputs(recvdata, stdout) == EOF) 
err_sys("fputs error"); 

你墊它蒙山一個「0」,因此當fputs解析字符串以便打印它時,它可能會導致您進入段錯誤。

希望它有幫助!

+0

在ASCII中,''\ 0'' =='0'。雖然沒有明確和使用''\ 0''的危害。 – michaelb958 2013-07-08 15:29:16

+0

很高興知道! :) :) :) ty! – user2561272 2013-07-09 11:16:27

相關問題