windows - C ++ Winsock vil fryse modtagelsesdata

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg laver et program med kode: Blokerer i C ++ For at sende og modtage data med Winsocks, men når jeg forsøger at modtage data, fryser mit program. Hjælp venligst. Jeg ved ikke hvorfor?
Jeg kunne kun få 1 linje uden at bruge en loop, så jeg tilføjede en loop for at se, om jeg kunne få flere linjer, der kommer ind, og nu fryser det bare.


#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);
}

Bedste reference


Det fryser, fordi det venter på data. Hvis du ikke vil vente på data, skal du ikke lave et Winsock-opkald, der gør det. Brug en af ​​de mange ikke-blokerende I/O-metoder, der er tilgængelige på Windows som Async operationer, I/O-afslutningsporte eller afslutningsbegivenheder. [2] [3]


Af den måde virker din kode meget ødelagt på mange måder. Det ser ud til at mangle en protokol . Du kan ikke bruge TCP uden at designe og implementere en protokol på toppen af ​​TCP.Du får fuldstændig upålidelig adfærd, hvis du ikke behandler de data, du har modtaget gennem en slags protokolmotor, der rekonstruerer de overførte oplysninger. I tilfælde af at nogen sender 'foo', vil den endelige tekst afhænge af, hvordan dataene blev samlet til transport. Det kan være 'foo', men det kan være 'o', da 'fo' kan overskrives.


Hvis den anden side sender linjer , som du hævder, skal du kode denne ende til modtage linjer. Det vil sige, at du skal beholde data indtil du har en linje, og ikke lade senere modtage overskrivning, tidligere modtager, så du kan genmontere den overførte linje. Koden til at virkeliggøre modtagelsen af ​​linjer mangler helt i koden du indsatte. (Hvis f.eks. En 'linje' er defineret som en masse byte, der er termineret af en nylinjetegn, skal der være kode for at søge efter newline-tegnene og samle alt før dem i en enkelt buffer til behandling.)