2011-08-31 95 views
2

我正在開發一個將數據流TCP套接字打開到另一個套接字的應用程序。 連接打開並被服務器接受後,我發送一個「登錄」消息,服務器成功接收到該消息,服務器嘗試發送「成功」消息。這是奇怪的地方。C - 在已打開的套接字上「拒絕連接」

服務器上的寫入失敗,並將errno設置爲「Broken pipe」。 客戶機輪詢文件描述符,等待數據讀取,也會失敗。在此errno被設置爲「連接被拒絕」。

環回設備上的所有連接均爲TCP。 使用tcpdump,我可以看到FIN從客戶端發送到服務器。 可以發現here

如果連接已建立,errno如何成爲「連接被拒絕」? 什麼可能導致此行爲?客戶端代碼是同步的,沒有任何線程,也沒有其他人可以訪問文件描述符。

如果重要,服務器是Asterisk管理器。客戶端代碼的

片段(真正的代碼有錯誤檢查,分離功能,這樣):

struct sockaddr_in sa; 
int fd; 

fd = sock_socket(SOCK_STREAM, 0, 0);. 
MZERO(sa); 
sa.sin_family = AF_INET; 
sa.sin_addr.s_addr = inet_addr("127.0.0.1"); 
sa.sin_port = htons(MANAGER_PORT); 

connect(fd, (struct sockaddr *)&sa, sizeof(sa)); 
sprintf(buf, 
    "Action: Login\r\n" 
    "Username: %s\r\n" 
    "Secret: %s\r\n" 
    "Events: %s\r\n" 
    "ActionID: %d\r\n" 
    "\r\n", 
    MANAGER_USERNAME, MANAGER_PASSWORD, events, manager_action_id++) 

write(fd, buf, strlen(buf)); 

{ 
    struct pollfd fds = {fd, POLLIN, 0}; 

    if (poll(&fds, 1, timeout) <= 0) 
     return -1; /* This is where the client fails with "Connection refused" */ 
} 

謝謝!

P.S. - 抱歉對問題內部的評論作出迴應,但是我在創建帳戶之前創建了問題,並且我不允許添加評論。

+4

您需要向我們展示您的客戶端源代碼。 –

+0

你確定沒有人調用'close'或'shutdown'嗎?你能告訴我們捕獲文件嗎? – cnicutar

+0

'poll'不應該以errno'ECONNREFUSED'返回-1。它可能已經返回0,在這種情況下,errno沒有設置;它只是從以前的系統調用中遺留下來。嘗試在'strace'下運行客戶端以確保調用和錯誤的順序正確。 – mark4o

回答

0

關於以「水管壞了」,我猜你是嘗試寫一些東西,在一個封閉的插座所以SIG_PIPE信號釋放,在這case.Declare <signal.h>和的方式安裝信號操作,如signal(SIG_PIPE,SIG_IGN)