2012-09-28 31 views
0

我遇到了運行一小塊代碼的問題。這是關於在C編程的套接字編程。我想要做的是讓客戶端與兩個不同端口上的服務器進行通信。但是,當我試圖編譯客戶端代碼時,我得到'分段錯誤'。我在這裏給我的客戶代碼。請讓我知道發生了什麼問題。段錯誤 - 套接字編程

#include<stdio.h> 
    #include<stdbool.h> 
    #include<string.h> 
    #include<stdlib.h> 
    #include<time.h> 
    #include <sys/types.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <netdb.h> 

    int main(int argc,char *argv[]) 
    { 
    int sockfd,newsockfd,sockfd_infinite,sockfd_kitchen,portno,portno1,n,no_of_tables; 
    struct sockaddr_in serv_addr,kitchen_addr; 
    struct hostent *server,*kitchen; 
    struct timeval time_out; 
    time_out.tv_sec = 15; // 15 seconds 
    time_out.tv_usec = 0; // 0 milliseconds 
    //  server=gethostbyname(argv[1]); 
    //  char buffer[256]; 
    portno=atoi(argv[2]); 
    portno1=atoi(argv[4]); 
    sockfd=socket(AF_INET,SOCK_STREAM,0); 
    if(sockfd==-1) 
      error("\nError creating socket"); 
    server=gethostbyname(argv[1]); 
    serv_addr.sin_family=AF_INET; 
    serv_addr.sin_port=htons(portno); 
    bcopy((char *)server->h_addr, 
      (char *)&serv_addr.sin_addr.s_addr, 
      server->h_length); 

    sockfd_kitchen=socket(AF_INET,SOCK_STREAM,0); 
    if(sockfd_kitchen==-1) 
      error("\nError creating socket"); 
    kitchen=gethostbyname(argv[3]); 
    kitchen_addr.sin_family=AF_INET; 
    kitchen_addr.sin_port=htons(portno1); 
    bcopy((char *)kitchen->h_addr, 
      (char *)&kitchen_addr.sin_addr.s_addr, 
      kitchen->h_length); 

    n=connect(sockfd_kitchen,(struct sockaddr *)&kitchen_addr,sizeof(kitchen_addr)); 
    if(n==-1) 
      error("\nError connecting to kitchen"); 
    n=connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); 
    if(n==-1) 
      error("\nError connecting to server"); 
    return 0; 
    } 

所以這個代碼背後的想法是 - 有一個客戶端,並有一個服務器。該客戶端想要在兩個不同的端口上與服務器通信,就好像客戶端正在與兩臺不同的服務器交談。我在我的筆記本電腦上爲服務器名稱和不同的端口號在服務器名稱中設置爲'localhost'。就像你在我的代碼中看到的一樣,我有兩個服務器的指針變量,即* server和* kitchen。

如: ./thiscode本地主機15535本地主機12345

在我所提到的例子,這是我怎麼編譯我的客戶端代碼。 argv [1]是第一個「localhost」(服務器名稱),argv [2]是第一個服務器的端口號。第二個「localhost」和「12345」是第二個服務器的名稱和端口號。

就像我以前說過的,我試圖在我的筆記本電腦上運行三個不同代碼的窗口(一個用於客戶端,另一個用於服務器)。我的兩個服務器代碼編譯沒有任何問題,但我的客戶端代碼得到這個'分段'錯誤。請讓我知道我要去哪裏錯了。 謝謝。

+1

短的編譯器中的一個錯誤,你_not_得到一個SEGV當你編譯。你跑步的時候就會得到它。在那裏,我已經達到了一天的配套定額:-) – paxdiablo

+0

當你在程序崩潰,分段錯誤或任何其他情況下,作爲程序員的第一反應應該是在調試器中運行你的程序。它將幫助您找到崩潰的位置,並讓您檢查變量以幫助您找出事故原因。 –

+0

幾點意見:(1)你的代碼在使用argv之前沒有檢查argc,所以如果你運行程序時沒有參數,那麼你會在那裏溢出。 (2)即使給出了正確的參數個數,你也應該檢查它們是否被正確解析。 (3)valgrind在運行此代碼時會產生大量輸出,因此您應該遵循Joachim的建議。 –

回答

0

一開始,則應該從gethostbyname被檢查返回值:

的的gethostbyname()和gethostbyaddr()函數返回hostent結構或一個NULL指針如果發生錯誤。出錯時,h_errno變量保存一個錯誤號。

+0

我沒有用HOST_NOT_FOUND值檢查h_errno。對於C中的普通服務器 - 客戶端套接字編程,即使h_errno等於HOST_NOT_FOUND,我仍然可以在服務器和客戶端之間傳輸數據。我不清楚這是怎麼發生的! – Richard

+1

@Richard,'h_errno'(就像'errno')是不相關的_unless返回值表示錯誤。_否則,它可以設置爲_any_值。換句話說,檢查函數是否返回NULL,並且只有在函數返回NULL時才查看'h_errno'。 – paxdiablo

0

看來問題出在bcopy()函數調用。

在將東西複製到它之前,您還沒有爲變量聲明空間,因此您看到了分段錯誤

bcopy()語句之前輸入以下代碼刪除賽格故障:

serv_addr.sin_addr.s_addr=malloc(sizeof(unsigned long));