2012-05-02 79 views
1

我嘗試使用Mac OS X下AF_UNIX插座,和我進行了一個包含某些信息的結構:socket失敗連接到服務器

typedef struct 
{ 
    int socket; 
    int conn; 
    struct sockaddr addr; 
}socket_info; 

我使用這些功能:

socket_info* server_init(void) 
{ 
    socket_info* result=(socket_info*)malloc(sizeof(socket_info)); 
    socklen_t length=sizeof(struct sockaddr); 
    bzero(&(result->addr),sizeof(struct sockaddr)); 
    result->socket=socket(AF_UNIX,SOCK_STREAM,0); 
    (result->addr).sa_family=AF_UNIX; 
    (result->addr).sa_len=sizeof(struct sockaddr); 
    strcpy((result->addr).sa_data,"./mysock"); 
    bind(result->socket,&(result->addr),length); 
    listen(result->socket,MAX); 
    result->conn=accept(result->socket,&(result->addr),&length); 
    return result; 
} 


socket_info* client_init(socket_info* info) 
{ 
    socket_info* result=(socket_info*)malloc(sizeof(socket_info)); 
    result->socket=socket(AF_UNIX,SOCK_STREAM,0); 
    while(connect(result->socket,&(info->addr),sizeof(struct sockaddr))==-1) 
    { 
    if(errno==ENOENT) 
    { 
     sleep(1); 
    } 
    else 
    { 
     fprintf(stderr,"Error: %d",errno); 
     free(result); 
     result=NULL; 
    } 
    } 
    return result; 
} 

我使用它們在主:

int main(int argc, char** argv) 
{ 
    socket_info *server_info, *client_info; 
    pid_t pid; 
    int fd[2]; 
    pipe(fd); 
    pid=fork(); 
    if(pid==0) 
    { 
    char buffer[100]; 
    read(fd[0], server_info, sizeof(struct sockaddr)); 
    client_info=client_init(server_info); 
    read(client_info->socket,buffer,100); 
    printf("Messaggio ricevuto: %s",buffer); 
    } 
    else 
    { 
    const char* msg="ciao"; 
    server_info=server_init(); 
    write(fd[1],server_info,sizeof(struct sockaddr)); 
    write(server_info->socket,msg,sizeof(msg)); 
    } 
    close(fd[0]); 
    close(fd[1]); 
    return 0; 
} 

但客戶端無法連接:相反,它打印消息:「錯誤:61」。
可能是什麼原因?

回答

3

你有兩個主要問題:

  1. 你有一個經典的比賽條件。如果客戶端在服務器設置爲偵聽之前嘗試連接,則客戶端將收到錯誤。

  2. 你的服務器不檢查任何錯誤,所以它可能會失敗,你不會知道它。

在任何一種情況下,您都會得到完全錯誤(連接被拒絕)。

我的錢是第一個問題。如果您翻轉客戶端和服務器,以便孩子成爲服務器,它可能會從「不發生作用」轉爲「發生作用」。大多數操作系統都會讓孩子先運行,因爲這樣可以節省內存,並且在孩子只需撥打exec的典型情況下就可以消除大量的頁面錯誤。

相關問題