2012-03-25 25 views
0

我正在使用Code :: Blocks的C++中的程序發送和接收數據Winsocks但是當我嘗試接收數據我的程序死機,請幫助。我不知道爲什麼? 我能夠在不使用循環的情況下獲得1行,因此我添加了一個循環以查看是否可以獲取更多行,現在它只是凍結。C++的Winsock將凍結接收數據

#define WIN32_LEAN_AND_MEAN 

#include <windows.h> 
#include "resource.h" 
#include <winsock.h> 

using namespace std; 

SOCKET mysocket; 
SOCKADDR_IN SockAddr; 
char buf1[120]; 
char buf2[120]; 
char ReadIp[120]; 
int UsePort; 
int n; 

HINSTANCE hInst; 

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(uMsg) 
    { 
     case WM_INITDIALOG: 
      WSADATA WsaDat; 
      WSAStartup(MAKEWORD(1,1), &WsaDat); 
      mysocket = socket(AF_INET, SOCK_STREAM, 0); 
      return TRUE; 

     case WM_CLOSE: 
      EndDialog(hwndDlg, 0); 
      return TRUE; 

     case WM_COMMAND: 
      switch(LOWORD(wParam)) 
      { 
       case IDC_BTN_QUIT: 
        EndDialog(hwndDlg, 0); 
        return TRUE; 

       case BtnSend: 
        GetDlgItemText(hwndDlg, PacketText, buf2, sizeof(buf2)); 
        send(mysocket, buf2, sizeof(buf2), 0); 
        return TRUE; 

       case IDC_BTN_TEST: 
        UsePort = GetDlgItemInt(hwndDlg, PortText, NULL, FALSE); 
        GetDlgItemText(hwndDlg, IpText, ReadIp, sizeof(ReadIp)); 
        SockAddr.sin_port = htons(UsePort); 
        SockAddr.sin_addr.s_addr=inet_addr(ReadIp); 
        SockAddr.sin_family = AF_INET; 
        connect(mysocket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)); 
        do { 
         n = recv(mysocket, buf1, sizeof(buf1), 0); 
        if (n > 0) 
         SetDlgItemText(hwndDlg, List1, buf1); 
        } while (n > 0); 
        return TRUE; 
        } 
    } 

    return FALSE; 
} 


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 
{ 
    hInst = hInstance; 

    // The user interface is a modal dialog box 
    return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc); 
} 

回答

1

它凍結,因爲它正在等待數據。如果您不想等待數據,請不要進行Winsock調用。使用Windows上提供的許多非阻塞I/O方法之一,如Async operationsI/O completion ports或完成事件。

順便問一下,你的代碼似乎打破不好在許多方面。它似乎缺少一個協議。如果沒有在TCP之上設計和實現協議,就不能使用TCP。如果您不處理通過重構傳輸信息的某種協議引擎接收到的數據,則會得到完全不可靠的行爲。例如,就你的情況而言,如果有人發送「foo」,最終的文本將取決於數據如何組裝以進行傳輸。它可能是「foo」,但它可能是「o」,因爲「fo」可以被覆蓋。

如果對方在發送,如權利要求你,你需要爲此代碼接收線。也就是說,您需要保持接收數據,直到您有一條線路,並且不讓稍後接收覆蓋較早的接收,以便您可以重新組裝傳輸的線路。實際實現接收行的代碼在您粘貼的代碼中完全沒有。 (如果,例如,「線」被定義爲一個束通過換行符終止字節,需要有代碼來搜索換行符和組裝它們之前都變成有利於處理一個單一的緩衝器。)

+0

你可以發佈一個例子嗎? – user1290713 2012-03-25 01:34:29

+0

如果我猜你想要給你什麼,這對你來說不太可能有用。你外在的問題是什麼?你想製作一臺服務器還是客戶端?你的過程是多線程的嗎?性能與易於編碼相比有多重要?你應該通過查看[WSAAsyncSelect(http://msdn.microsoft.com/en-us/library/windows/desktop/ms741540%28v=vs.85%29.aspx)開始。對於單線程,低性能的Windows事件循環客戶端來說,這是很好的選擇。 – 2012-03-25 01:41:31

+0

這就是它的簡單代碼,就像windows Telnet中的命令一樣,只需連接並可以接收和發送,也可以用來讀取數據包。我看FD_READ這樣的例子看起來毫無用處。 – user1290713 2012-03-25 01:47:32