2015-06-02 143 views
-2

我試圖創建一個與自身連接的程序。 我觸發一個線程客戶端和一個線程服務器,併爲每個線程創建一個套接字。我使用相同的端口。C連接失敗套接字

當線程客戶端嘗試連接到線程服務器時,連接失敗。爲什麼?我無法理解。幫我!

完整的代碼很複雜,因爲它很大。但我會概括。

#define ADDR "127.0.0.1" 

struct threadData{ 
    int portnum; 
    int sockid; 
    int lastID; 
    unsigned int lastCheck; 
}; 

// ----------- ----- Connection ------ ------------- // 

void dieError(char *message, int socket){ 
    printf("%s\n", message); 
    if(socket != 0) 
     close(socket); 
    exit(1); 
} 

int createSocket(int portnum, struct sockaddr_in* netw){ 
    int sockid; 

    sockid = socket(AF_INET, SOCK_STREAM, 0); 
    if(sockid == -1) 
     dieError("socket() failed", sockid); 

    struct in_addr addrr; 
    if(inet_pton(AF_INET, ADDR, &addrr) < 1) 
     dieError("pton() failed", sockid); 

    netw->sin_family = AF_INET; 
    netw->sin_port = htons(portnum); 
    netw->sin_addr = addrr; 

    return sockid; 
} 

void listenSocket(struct threadData* thd, struct sockaddr_in* netw){ 

    if(bind(thd->sockid, (struct sockaddr *) netw, sizeof(struct sockaddr)) == -1) 
     dieError("bind() failed", thd->sockid); 

    if(listen(thd->sockid, 0) == -1) 
     dieError("listen() failed", thd->sockid); 
} 

int acceptConnection(int sockid, struct sockaddr* addrr){ 
    socklen_t cLen = sizeof(struct sockaddr); 
    int cSocket = accept(sockid, addrr, &cLen); 

    if(cSocket == -1) 
     dieError("accept() failed", sockid); 

    return cSocket; 
} 

int createConnection(int portnum, struct sockaddr_in* netw){ 
    int sockid = createSocket(portnum, netw); 

    fcntl(sockid, F_SETFL, O_NONBLOCK); 

    if(connect(sockid, (struct sockaddr *) netw, sizeof(struct sockaddr)) == -1) 
     dieError("connect() failed", sockid); 

    return sockid; 
} 

// ----------- ----- ---------- ------ ------------- // 

//Receptor thread 
void * verifyPort(void * param){ 
    struct threadData* thd = param; 
    int cSocket; 
    struct sockaddr addrr; 
    struct sockaddr_in* netw = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); 

    thd->sockid = createSocket(thd->portnum, netw); 
    listenSocket(thd, netw); 
    cSocket = acceptConnection(thd->sockid, &addrr); 
} 

//Sender thread 
void verifyKeyboard(int portnum){ 
    int sockid; 
    struct sockaddr_in* netw = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); 
    sockid = createConnection(portnum, netw); 
} 

// ----------- ---- -------- ------- ------------- // 

int main(int argc, char **argv){ 
    pthread_t tid; 
    struct threadData* thd; 
    thd = (struct threadData*) malloc(sizeof(struct threadData)); 

    thd->portnum = atoi(argv[1]); 
    thd->lastID = -1; 
    thd->lastCheck = 0; 

    pthread_create(&tid, NULL, verifyPort, thd); 

    verifyKeyboard(atoi(argv[1])); 

    free(thd); 

    return 0; 
} 
+1

可能值得用['strerror(errno)']打印錯誤信息(http://man7.org/linux/man-pages/man3/strerror.3.html)('strerror'在' '和'errno'在''中定義) – Frxstrem

+3

可能完整的代碼會有所幫助。 – CristiFati

+0

失敗如何?無法連接?超時?什麼也沒做?獲取重置? – EJP

回答

1

對我來說,就像你在客戶線程中將錯誤的地址結構大小傳遞給connect()一樣。這:

if (connect(sockid, addrr, sizeof(struct sockaddr)) == -1) 

大概應該是:

if (connect(sockid, addrr, sizeof(struct sockaddr_in)) == -1) 

,表明你正在傳遞一個互聯網地址connect()sizeof(struct sockaddr)顯然是錯誤的,因爲這只是泛型結構類型。

沒有更多的代碼就很難查明其他問題。

+0

我修復了我寫錯的代碼,但連接()的地址結構的大小是strcut sockaddr。 ''' int connect(int sockfd,const struct sockaddr * addr,socklen_t addrlen); ''' [http://man7.org/linux/man-pages/man2/connect.2.html](http://man7.org/linux/man-pages/man2/connect.2.html ) – Jeff

+0

@Jeff sockaddr是針對各種地址系列特定結構的一種傘型。它的大小可能小於或大於sockaddr_in這樣的實際地址結構,否則根本不需要addrlen。 – user3125367

+0

@Jeff:Filipe是對的,你需要傳遞'connect()'你傳遞的實際套接字地址結構的大小,在這種情況下'sizeof * netw'。考慮一下,如果你總是必須傳遞它'sizeof(struct sockaddr)',爲什麼你需要傳遞它呢? – caf