2012-12-13 54 views
0

我正在用C++開發一個簡單的服務器/客戶端聊天應用程序,使用unix套接字,還有一件事困擾着我。帶PSH消息的客戶端垃圾郵件服務器

如果我在終端(我正在使用mac)中運行聊天客戶端並使用CTRL + C關閉客戶端,則完成四次握手並且連接關閉正確。

如果我選擇關閉終端窗口,客戶端正在運行,客戶端會向服務器發送一堆數據包。

關閉客戶端,CTRL + C:

enter image description here

關閉客戶端通過關閉終端窗口:

enter image description here

將是巨大的,如果有人能向我解釋發生了什麼。

客戶端代碼:

void writeString(int FD, const char* data, size_t n){ 
    size_t bytesLeft = n; 
    ssize_t bytesWritten = 0; 
    const char *cBuffer = (char*) data; 
    while ((bytesWritten = write(FD, cBuffer, bytesLeft)) > 0) { 
    bytesLeft -= bytesWritten; 
    cBuffer += bytesWritten; 
    } 
} 

bool writeInt(int FD, int intToWrite){ 
    intToWrite = htonl(intToWrite); 
    write(FD, &intToWrite, sizeof(intToWrite)); 
} 

void writeMessage(int FD, int type, int ID, string message){ 
    if(type == 1){ 
    int messageSize = (int) message.length(); 
    writeInt(FD, type); 
    writeInt(FD, ID); 
    writeInt(FD, messageSize); 
    writeString(FD, message.c_str(), messageSize); 
    } 
} 

while (!connectionClosed) { 
FD_SET(socketFD, &rset); 
FD_SET(0, &rset); 
int maxfd = max(0, socketFD) + 1; 

select(maxfd, &rset, NULL, NULL, NULL); 

if(FD_ISSET(0, &rset)){ 
    getline(cin, input); 
    writeMessage(socketFD, 1, ID, input); 
}else if(FD_ISSET(socketFD, &rset)){ 
    int type = 0; 
    if(readInt(socketFD, type) == 0) 
    connectionClosed = true; 
    readMessage(socketFD, type, ID); 
} 
} 

close(socketFD); 
+0

無法確定,但您可能需要處理'SIGHUP'來捕捉遠離的終端窗口,然後關閉套接字並退出。 –

+0

但是爲什麼即使在應用程序關閉後,它仍然在發送數據包? – Carlj901

+0

你確定你的應用程序已經沒有了嗎?在Mac上關閉窗口不會退出應用程序。看看進程的清單是肯定的。 –

回答

0

我的猜測是,當你關閉終端與關閉按鈕它發送一些標準的終端命令來結束會話(session)PTY。由於您的聊天應用程序正在運行,因此您的聊天應用程序會攔截並轉發到服務器。

例如,telnet協議包含很多事情的控制代碼,包括中斷和中止正在運行的進程。

你看過正在發送的實際數據包內容嗎?

關於PSH(推)中的解釋相當不錯這裏例如:
http://packetlife.net/blog/2011/mar/2/tcp-flags-psh-and-urg/

您可能還需要記錄在您的客戶端應用程序添加到磁盤上,這樣就可以在以後檢查發生了什麼事情,你關閉終端窗口。

甚至將調試會話從另一個終端窗口附加到正在運行的客戶端。

+0

博客對PSH標誌不正確。它基本上被接收器忽略:*所有*數據立即提供給應用程序,無論是否PSH-ed。它是在API之前設計的:顯然某種中斷回調最初是設想的。然而,PSH在幾種情況下仍然被設置,例如,在FIN上。 – EJP

相關問題