2012-03-25 18 views
0

C++でCode :: Blocksを使用してプログラムを作成していますが、データを受信しようとするとプログラムがフリーズします。どうしてか分かりません? ループを使用せずに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の呼び出しをしないでください。 Async operations,I/O completion portsまたは完了イベントなど、Windows上で利用可能な多くのノンブロッキングI/Oメソッドの1つを使用します。

ところで、あなたのコードは多くの点でひどく壊れているようです。それはプロトコルが欠けているようです。 TCPの上にプロトコルを設計し実装することなく、TCPを使用することはできません。送信された情報を再構成する何らかのプロトコルエンジンによって受信したデータを処理しないと、信頼性の低い動作が発生します。たとえば、あなたの場合、誰かが "foo"を送ると、最終的なテキストはデータがどのように組み立てられて輸送されるかによって決まります。それは "foo"かもしれませんが、 "fo"は上書きできるので "o"かもしれません。

あなたが主張するように、他の側は、ラインを送信している場合は、ラインを受け取るには、このエンドをコーディングする必要があります。つまり、回線があり、あらかじめ上書きされた受信を受信しないようにして、送信された回線を再構築できるようになるまで、データを受信し続ける必要があります。行の受信を実際に実装するコードは、貼り付けたコードには完全にありません。 (例えば、 "行"が改行文字で終わるバイト群として定義されている場合は、改行文字を検索してその前のすべてを処理するために単一のバッファにアセンブルするコードが必要です)。

+0

彼らの1つの例を掲示することができます – user1290713

+0

私はあなたに何を与えるかを推測すればあなたにとって有用ではありそうもありません。あなたの外の問題は何ですか?サーバーやクライアントを作ろうとしていますか?あなたのプロセスはマルチスレッドですか?コーディングの容易さに比べてパフォーマンスはどれくらい重要ですか?まず、[WSAAsyncSelect](http://msdn.microsoft.com/en-us/library/windows/desktop/ms741540%28v=vs.85%29.aspx)を参照してください。これは、シングルスレッド、低パフォーマンスのWindowsイベントループクライアントに適しています。 –

+0

WindowsのTelnetのコマンドのようにシンプルなコード全体を接続して受信して送ることができるので、パケットを読み込むこともできます。 FD_READのようなケースは役に立たないように見えます。 – user1290713