2012-03-25 56 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