Toon posts:

[C/C++] async. winsock server socket

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ziehier mijn eerste poging om een multithreaded server te schrijven.

Het probleem is hetvolgende : Wanneer ik met een client (netcat in dit geval) verbind naar de server en text doorstuur, krijg ik onmiddelijk een popup vd server-app met de betreffende text, als ik deze boodschap wegklik, komt hij steeds weer opnieuw terug met dezelfde msg !? (ipv te wachten tot er weer data pending is op de client socket.)

Omdat de buffer (pszTemp) word ge-cleared voor iedere recv() kan de msg niet keer na keer hetzelfde zijn - of de data moet nog steeds pending zijn op de socket...

Moet ik op een of andere manier de socket duidelijk maken dat de data erafgehaald is ???


Korte samenvatting vd code:
In de WM_CREATE word de InitServer() func. aangeroepen, deze bind de m_ServerSocket aan alle locale adapters op poort 8585 en vraagt met AsyncSelect om notification te ontvangen voor incomming connections (FD_ACCEPT).
Bij de accept van de connectie wordt er een nieuwe thread gestart die de client moet verderhelpen. En hier loopt het verkeerd : ioctlsocket beweerd dat er steeds data pending is op de socket.


Wat doe ik verkeerd ??? :? Iemand ?
Alle hulp is welkom !



code:
1
2
3
4
5
6
7
8
9
10
11
12
13
// Custom message to receive notification of socket acitvity (WSAAsyncSelect)
#define WM_SOCKET_NOTIFY        WM_USER + 1

// struct for passing data between main program and client threads
typedef struct
{
    SOCKET  socket;
    HWND    hWnd;

} PARAMS, *PPARAMS;

// The server socket variable
SOCKET          m_ServerSocket;


De Main Window Proc :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) 
    {
    case WM_SOCKET_NOTIFY:
        {
            wEvent = WSAGETSELECTEVENT (lParam) ;   // ie, LOWORD
            wError = WSAGETSELECTERROR (lParam) ;   // ie, HIWORD

            if (wEvent == FD_ACCEPT)
            {
                // An incomming connection is pending, 
                // start a new thread to handle the client
                SOCKET theClient;
                theClient = accept(m_ServerSocket,
                        NULL,
                        NULL);
                if (theClient == INVALID_SOCKET) 
                {
                    MessageBox(hWnd, _T ("accept error \n"), _T("error"), MB_OK);
                    WSACleanup();
                    return 0;
                }
                parameters.hWnd = hWnd;
                parameters.socket = theClient;
                _beginthread(ClientProc, 0, &parameters);
            }


        }
        break;
    case WM_CREATE:
        InitServer(hWnd);
        break;
.....
    case WM_DESTROY:
            closesocket(m_ServerSocket);
            WSACleanup();
            PostQuitMessage(0);
            break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}


De InitServer() Proc :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
void InitServer(HWND hWnd)
{
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);

    m_ServerSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP) ;
    
    if (m_ServerSocket == INVALID_SOCKET)
    {
        MessageBeep(MB_OK);
        MessageBox(hWnd, _T("Socket creation failed"), _T("error"), MB_OK);
        WSACleanup () ;
        PostQuitMessage(0);
        return;
    }

    // Async select - notify on incomming connection (FD_ACCEPT)
    if (SOCKET_ERROR == WSAAsyncSelect (m_ServerSocket, hWnd, WM_SOCKET_NOTIFY, 
                                                   FD_ACCEPT))
    {
        MessageBox(hWnd, _T ("WSAAsyncSelect error \n"), _T("error"), MB_OK);
        closesocket(m_ServerSocket) ;
        WSACleanup();
        PostQuitMessage(0);
        return;
    }

    // Bind the socket to our local server address
    SOCKADDR_IN saServer;
    saServer.sin_family = AF_INET;
    saServer.sin_addr.s_addr = INADDR_ANY;      // Bind to all nic's
    saServer.sin_port = htons(8585);        // Use port 8585

        int nRet = bind(m_ServerSocket, (LPSOCKADDR)&saServer, sizeof(struct sockaddr));
    if (nRet == SOCKET_ERROR)
    {
        MessageBox(hWnd, _T ("bind error \n"), _T("error"), MB_OK);
        closesocket(m_ServerSocket) ;
        WSACleanup();
        PostQuitMessage(0);
        return;
    }

    nRet = listen(m_ServerSocket, 10);      // 10 is the number of clients that can be queued
    if (nRet == SOCKET_ERROR) 
    {
        MessageBox(hWnd, _T ("listen error \n"), _T("error"), MB_OK);
        WSACleanup();
        return;
    }
}


En Natuurlijk de Client proc : (deze is niet async.)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void ClientProc(PVOID pvoid)
{
    PPARAMS parameters;
    parameters = (PPARAMS)pvoid;

    SOCKET clientSocket = parameters->socket;

    TCHAR* pszTemp = new TCHAR[MAX_PATH];

    fd_set fds_w, fds_r;

    while (true)
    {
        memset(pszTemp, 0, sizeof(TCHAR) * MAX_PATH);
        FD_ZERO(&fds_r); 
        FD_ZERO(&fds_w); 
        FD_SET(clientSocket,&fds_r);
        FD_SET(clientSocket,&fds_w);
    
        select(0, &fds_r, &fds_w, NULL, NULL);

        int read = FD_ISSET(clientSocket, &fds_r);
        int write = FD_ISSET(clientSocket, &fds_w);

        if (read!=0)
        {
            ioctlsocket(clientSocket, FIONREAD, &ulSize);
            recv(clientSocket, pszTemp, ulSize , MSG_PEEK);

            //parameters->hWnd
            MessageBox(NULL, pszTemp, _T("Incoming"), MB_OK);
        }

    }
    delete[] pszTemp;
    closesocket(clientSocket);

    _endthread();
}

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Value: MSG_PEEK
Meaning: Peeks at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function then returns the number of bytes currently pending to receive.

Gewoon 0 ipv MSG_PEEK gebruiken als flag.

www.madwizard.org


Verwijderd

Topicstarter
_/-\o_ _/-\o_

Super ! Hier ben ik nu al een week naar opzoek !

Serieus bedankt ! :*)


edit:

Hail ska ! :P