2013-04-16 82 views
0

以下代碼在Ubuntu上運行並與客戶端通信時沒有問題。但是,我需要在Mac OS X上運行。我可以在沒有錯誤的情況下編譯它,但是當我嘗試運行它時,會出現以下消息:「中止陷阱:6」。我試圖谷歌它,但無法找到任何有用的信息。即使我在主函數的開始處放置printf,它也不會運行。謝謝你的任何建議。未在Mac OS X上運行的C套接字

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/un.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 
#define UNIX_PATH_MAX 108 

int connection_handler(int connection_fd) 
{ 
    int nbytes; 
    char buffer[256]; 

    nbytes = read(connection_fd, buffer, 256); 
    buffer[nbytes] = 0; 

    printf("MESSAGE FROM CLIENT: %s\n", buffer); 
    nbytes = snprintf(buffer, 256, "hello from the server"); 
    write(connection_fd, buffer, nbytes); 

    close(connection_fd); 
    return 0; 
} 

int main(void) 
{ 
    struct sockaddr_un address; 
    int socket_fd, connection_fd; 
    socklen_t address_length; 
    pid_t child; 

    socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); 

    if(socket_fd < 0) 
    { 
     printf("socket() failed\n"); 
     return 1; 
    } 

    unlink("./demo_socket"); 

    /* start with a clean address structure */ 
    memset(&address, 0, sizeof(struct sockaddr_un)); 
    address.sun_family = AF_UNIX; 
    snprintf(address.sun_path, UNIX_PATH_MAX, "./demo_socket"); 

    if(bind(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) 
    { 
     printf("bind() failed\n"); 
     return 1; 
    } 

    if(listen(socket_fd, 5) != 0) 
    { 
     printf("listen() failed\n"); 
     return 1; 
    } 

    while((connection_fd = accept(socket_fd, (struct sockaddr *) &address,&address_length)) > -1) 
    { 
     child = fork(); 
     if(child == 0) 
     { 
      /* now inside newly created connection handling process */ 
      return connection_handler(connection_fd); 
     } 
     /* still inside server process */ 
     close(connection_fd); 
    } 

    close(socket_fd); 
    unlink("./demo_socket"); 
    return 0; 
} 
+0

您可能想要在調試器中運行它。 –

+0

''connection_handler'引起了我的注意的一點是你不會檢查'read'調用中的錯誤。當它失敗並返回'-1'時,會發生什麼? –

回答

0

一個可能的原因是,你不打電話accept前初始化address_lengthaccept需要它在調用之前被正確初始化。

4

你有UNIX_PATH_MAX硬編碼爲108,但在sun_pathsockaddr_un只有104個字節長:

struct sockaddr_un { 
    unsigned char sun_len; /* sockaddr len including null */ 
    sa_family_t sun_family; /* [XSI] AF_UNIX */ 
    char  sun_path[104]; /* [XSI] path name (gag) */ 
}; 

所以你想用下面的緩衝外面寫:

snprintf(address.sun_path, UNIX_PATH_MAX, "./demo_socket"); 

您可以修復此問題:

snprintf(address.sun_path, sizeof(address.sun_path), "./demo_socket"); 

如果你使用了一個調試器(比如gdb),這將是一個簡單的修復。