我正在開發一個將數據流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. - 抱歉對問題內部的評論作出迴應,但是我在創建帳戶之前創建了問題,並且我不允許添加評論。
您需要向我們展示您的客戶端源代碼。 –
你確定沒有人調用'close'或'shutdown'嗎?你能告訴我們捕獲文件嗎? – cnicutar
'poll'不應該以errno'ECONNREFUSED'返回-1。它可能已經返回0,在這種情況下,errno沒有設置;它只是從以前的系統調用中遺留下來。嘗試在'strace'下運行客戶端以確保調用和錯誤的順序正確。 – mark4o