2012-01-22 27 views
0


它適用於Debian 5.0,但它會導致分段錯誤在Ubuntu 11.10

我希望我沒有得到消息的每噸這是轉儲問題。我真的試圖找出問題出在哪裏,但我不知道爲什麼在一個linux上工作並在其他linux上導致分段錯誤。所以當我在第一臺計算機上運行它時,它工作正常,但是當我在第二臺計算機上運行它時,它會導致分段錯誤,並且我收到消息SIGSEGV。

電腦頭號具有配置:
貓的/ etc /問題得到:的Debian GNU/Linux的5.0
UNAME -a得到:Linux的eryx2 2.6.34.4servgs#3 SMP太陽8月22日〇時38分18秒CEST 2010 i686的GNU/Linux的
計算機二號人物已經配置:
貓的/ etc /問題得到:Ubuntu的11.10
UNAME -a得到:Linux操作系統Ubuntu 3.0.0-15泛型#25,Ubuntu的SMP週一1月2日17:44:42 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

我附上我的應用程序的代碼。
1.I運行服務器 - 確定
2.I運行客戶端
3.Client發送消息到服務器
4.Server嘗試從服務器收到的消息,它會導致段故障

但這個問題只有在Ubuntu上運行它時,我已經指定它運行正常。

我也建立resp。編譯每個系統的源代碼。

服務器:

#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h> 
#include <sys/un.h> 
#include <unistd.h> 
#include <netinet/in.h> 
#include <unistd.h> 
#include <signal.h> 
#include <stdlib.h> 

int sendMessage(char* msg, int socket){ 
    int length = strlen(msg); 
    int ret; 

    ret = write(socket, msg, length); 
    return ret; 
} 

int readLine(void *vptr, size_t maxlen, int sockd) { 
    int n, rc; 
    char c, *buffer; 

    buffer = vptr; 

    for (n = 1; n < maxlen; n++) { 

     if ((rc = read(sockd, &c, 1)) == 1) { 
      *buffer++ = c; 
      if (c == '\n') 
       break; 
     } 
     else if (rc == 0) { 
      if (n == 1) 
       return 0; 
      else 
       break; 
     } 

    } 

    *buffer = 0; 
    return n; 
} 

int main() 
{ 
    int server_sockfd, client_sockfd; 
    int server_len, client_len; 
    struct sockaddr_in server_address; 
    struct sockaddr_in client_address; 


    server_sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    server_address.sin_family = AF_INET; 
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    server_address.sin_port = htons(10000); 

    server_len = sizeof(server_address); 

     if(bind(server_sockfd, (struct sockaddr *)&server_address, server_len) != 0) 
     { 
       perror("oops: server-tcp-single"); 
       exit(1); 
     } 

    listen(server_sockfd, 5); 

    signal(SIGCHLD, SIG_IGN); 

    while(1) 
    { 
     char ch; 

     printf("server wait...\n"); 

     client_len = sizeof(client_address); 
     client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); 

     printf("Connected client from %s\n", inet_ntoa(client_address.sin_addr)); 

     if(fork() == 0) 
     { 
      char retezec[20]; 
      readLine(retezec, 20, client_sockfd); 

      printf("Klient sent : %s\n", retezec); 
      printf("Server sends : %s\n", retezec); 
      sendMessage(retezec, client_sockfd); 
       close(client_sockfd); 

      exit (0); 
     } 
     else 
      close(client_sockfd); 

    } 
} 

客戶

import java.io.*; 
import java.net.*; 

class clientTCP 
{ 
    private static PrintWriter pw; 
    private static BufferedReader br; 

    private static void sendToServer(String msg) { 
      try 
     { 
       pw.println(msg); 
       //System.out.println(msg); 
       System.out.println("Klient poslal: " + msg); 
      } 
     catch (Exception e) 
     { 
      // System.out.println("e.Message"); 
      } 
    } 

    private static String recieveFromServer() { 
     String msg = "Chyba"; 
     try 
     { 
       msg = br.readLine(); 
       //System.out.println(msg); 
       System.out.println("Klient prijal: " + msg); 
     } 
     catch (Exception e) 
     { 
       System.out.println("Selhalo prijimani zpravy zpravy!"); 
       //System.out.println(e.Message); 
     } 
     return msg; 
    } 

public static void main(String argv[]) throws Exception 
{ 
    Socket socket = new Socket("127.0.0.1", 10000); 
    InetAddress adresa = socket.getInetAddress(); 
    System.out.print("Pripojuju se na : "+adresa.getHostAddress()+" se jmenem : "+adresa.getHostName()+"\n"); 

    pw = new PrintWriter(socket.getOutputStream(), true); 
    br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    sendToServer("ahoj\n"); 
    String message = recieveFromServer(); 
    //System.out.println("Message Received: " + message); 
    socket.close(); 
} 
} 

感謝。

編輯Java和版本的GCC:

第一臺計算機的Debian:
Java版本 「1.6.0_20」
的Java(TM)SE運行時環境(建立1.6.0_20-B02)
的Java熱點(TM)服務器VM(構建16.3-B01,混合模式)

gcc版本4.3.2(Debian的4.3.2-1.1)

第二計算機的Ubuntu
Java版本 「1.6.0_26」
的Java(TM)SE運行時環境(建立1.6.0_26-B03)
爪哇熱點(TM)64位服務器VM(構建20.1-B02,混合模式)

gcc版本4.6.1(Ubuntu/Linaro 4.6。1-9ubuntu3)

編輯:問題解決trought dicusion和谷歌搜索
所以我加入的變化,它可以幫助人用類似的問題。
有在服務器幾個問題:的 代替

int server_len, client_len; 

我應該使用 socklen_t str_len, client_len;
然後,而不是這個(這是段錯誤的原因): 的printf(「從%連接的客戶端s \ n「,inet_ntoa(client_address.sin_addr)); 我應該使用函數inet_ntop因爲我發現inet_ntoa已棄用。 seg故障的原因是我使用%s,所以arg的printf預計爲char * 這是更好的解決方案,我希望也能清楚。

char str[INET_ADDRSTRLEN]; 
inet_ntop(AF_INET,&(client_address.sin_addr), str, INET_ADDRSTRLEN); 
printf("Connected client from %s\n", str); 

我不知道這個問題是什麼,因爲我得到了很好的答案trouht評論和我的工作。 所以我至少添加了解決問題所需的修復程序。

+0

兩臺機器上的Java和gcc的版本是什麼? – Makoto

+0

請自己幫忙,並修正用'-Wall'指出的所有編譯C代碼的問題。 – Mat

+0

您能告訴我們seg故障發生在哪裏嗎?用調試器加載核心轉儲時看到了什麼? –

回答

1

我會確保你總是在最後設置\0。你有一個呼叫者忽略的return 0。這意味着如果char []在數組中沒有\0字節,您可能會遇到seg錯誤。

0

我遇到同樣的問題。這是因爲你沒有包括

#include <arpa/inet.h> 

這導致隱式聲明編譯代碼。隱式聲明方法總是返回其他類型的int instread(如char *)。

賽格故障時

的printf( 「%s的\ n連接的客戶端」,INET_NTOA( client_address.sin_addr));

因爲inet_ntoa()返回一個地址並被轉換爲0xffffffffef7dde20,這是超出範圍。 inet_ntoa的返回值被視爲32位整數。

您解決了inet_ntop的問題,而不是因爲inet_ntop是解決方案,如果使用inet_ntop的返回值作爲printf的參數,您仍然會收到段錯誤。