how to use WSAConnect and WSAAccept for sending receving init Data before accept a request

StackOverflow https://stackoverflow.com/questions/16247621

  •  13-04-2022
  •  | 
  •  

سؤال

As title, I 've searched in msdn or on internet for an example but I didn't find any one >_<
All case they use WSAConnect ( S, sa, sa_len ,NULL ,NULL ,NULL ,NULL );
I wanna use those function (WSAConnect & WSAAccept) for a simple authority with key in lpCallerData->buf before accept
I 've tried the example about WSAAccept from msdn for server side and my simple code about WSAConnect but It's alway "lpCallerData == NULL"
Sorry about my bad english
Thank you in advance with any help!

My not working code:

Server side:

SOCKET              SV_Socket;
struct sockaddr_in  SV_Channel;
WORD                SV_wVersionRequested;
WSADATA             SV_wsaData;
int                 SV_on = 1;

int CALLBACK ConditionAcceptFunc(
    LPWSABUF lpCallerId,
    LPWSABUF lpCallerData,
    LPQOS pQos,
    LPQOS lpGQOS,
    LPWSABUF lpCalleeId,
    LPWSABUF lpCalleeData,
    GROUP FAR * g,
    DWORD_PTR dwCallbackData
    )
{
    //printf( "test1\n" );

    //if ( memcmp( lpCallerData->buf ,"quyen194" , lpCallerData->len ) == 0 ) 
    if ( lpCallerData->buf[0] == 'q' ) 
    {

        //memcpy( lpCalleeData->buf ,"OK" ,2 );
        //lpCalleeData->len = 2;

        return CF_ACCEPT;
    }
    else
    {
        //printf( "Reject request: \n" );
        //printf( "Buf: " );
        //printf( lpCallerData->buf );
        //printf( "\nLen: %d\n" ,lpCallerData->len );
        //memcpy( lpCalleeData->buf ,"NOT" ,3 );
        return CF_REJECT;
    }
}
void AcceptRequest()
{
    struct sockaddr_in saClient;
    int iClientSize = sizeof(saClient);


//---- ACCEPT connection ------------------
    while(true){
        int socketNumb = 0;
        if(AcceptRequestFunctionLogOnScreen)
            if(AllSuccessLogOnScreen)
                printf("%d: Data Transfer Listen Socket Waiting...\n",socketNumb);



        //C_Socket = accept(SV_Socket,NULL,NULL);   // block for connection request 
        C_Socket = WSAAccept(SV_Socket, (SOCKADDR*) &saClient, &iClientSize, &ConditionAcceptFunc, NULL);



        if(C_Socket == INVALID_SOCKET)
        {
            if(AcceptRequestFunctionLogOnScreen)
                if(AllErrorLogOnScreen)
                    printf("%d: Data Transfer Listen Socket accept failed with error: %ld\n",socketNumb,WSAGetLastError());
            WSACleanup();
        }
        else{
            if(AcceptRequestFunctionLogOnScreen)
                if(AllSuccessLogOnScreen)
                    printf("%d: Request to Data Transfer Listen Socket Accepted...\n",socketNumb);
            //Mark that Client Socket is inused
            C_Alive = true;
            //---- SEND bytes -------------------------------------------
            CreateThread(NULL,NULL,LPTHREAD_START_ROUTINE(DataSending),NULL,NULL,NULL);
            CreateThread(NULL,NULL,LPTHREAD_START_ROUTINE(DataReceiving),NULL,NULL,NULL);
            while(C_Alive == true){
                Sleep(10000);
            }
        }
    }   

    while(shutdown(SV_Socket,SD_BOTH)){
        Sleep(1000);
    }
    closesocket(SV_Socket);
    WSACleanup();
    return;
}

Client side:

void Connect2Server()
{
    struct sockaddr_in saClient;
    int iClientSize = sizeof(saClient);
    LPWSABUF lpCallerData= new(WSABUF);
    //WSABUF lpCalleeData;// = new(WSABUF);

    lpCallerData->buf[0] = 'q';
    lpCallerData->len = 1;
        printf( "Source: \n" );
        printf( "Buf: " );
        printf( lpCallerData->buf );
        printf( "\nLen: %d\n" ,lpCallerData->len );

    system("pause");
    //---- try CONNECT -----------------------------------------
    int ReturnValue;
    int TryToConnect;
    int One_socketNumb = 0;
    for(TryToConnect=0;TryToConnect<=10;TryToConnect++)
    {
        //ReturnValue = connect(C_Socket,(SOCKADDR *)&C_Channel, sizeof(C_Channel));

        ReturnValue = WSAConnect( C_Socket ,(SOCKADDR *)&C_Channel ,sizeof(C_Channel) ,lpCallerData ,NULL ,NULL ,NULL );

        //printf( "Result: \n" );
        //printf( "Buf: " );
        //printf( lpCalleeData->buf );
        //printf( "Len: %d\n" ,lpCalleeData->len );

        if (ReturnValue == SOCKET_ERROR){
            if(Connect2ServerFunctionLogOnScreen)
                if(AllErrorLogOnScreen){
                    printf("%d: Connect error %ld",One_socketNumb,WSAGetLastError());
                    printf("%d: Attempt to connect #%d to ChatP2P Server\n",One_socketNumb,TryToConnect+1);
                }
            Sleep(1000);
            if (TryToConnect == 10)
            {
                WSACleanup();
                return; //Couldn't connect
            }
        }
        else{
            break;
        }
    }
    //-----------------------------------------------------------   
    if(Connect2ServerFunctionLogOnScreen)
        if(AllSuccessLogOnScreen)
            printf("%d: Connect ServerSOCKET: OK...\n",One_socketNumb);
    //Mark that Server Socket is inused
    C_Alive = true;

    //---Connection OK
    if(Connect2ServerFunctionLogOnScreen)
        if(AllSuccessLogOnScreen)
            printf("\n%d: Connected\n",One_socketNumb);
    //---- SEND bytes -------------------------------------------
    CreateThread(NULL,NULL,LPTHREAD_START_ROUTINE(DataSending),NULL,NULL,NULL);
    CreateThread(NULL,NULL,LPTHREAD_START_ROUTINE(DataReceiving),NULL,NULL,NULL);
    while(C_Alive == true){
        Sleep(10000);
    }
    //---Close Client Socket----------
    shutdown(C_Socket,SD_BOTH);
    closesocket(C_Socket);
    //-------------------------------------

    if(Connect2ServerFunctionLogOnScreen)
        if(AllSuccessLogOnScreen)
            printf("%d: Disconnected\n",One_socketNumb);
    WSACleanup();
    return;
}
هل كانت مفيدة؟

المحلول

lpCallerData is always NULL in your WSAAccept() callback because TCP/IP does not support exchanging caller/callee data during connection establishment. This is clearly stated in the WSAConnect() documentation:

Note Connect data is not supported by the TCP/IP protocol in Windows. Connect data is supported only on ATM (RAWWAN) over a raw socket.

The WSAAccept() documentation also states:

If no caller identification or caller data is available, the corresponding parameters will be NULL. Many network protocols do not support connect-time caller data.

...

The lpCalleeData->len initially contains the length of the buffer allocated by the service provider and pointed to by lpCalleeData->buf. A value of zero means passing user data back to the caller is not supported.

With that said, even if it were supported, you are not managing the WSABUF structures correctly anyway. Your server is not checking for NULL or len overflows, and your client code is not allocating any memory for the WSABUF::buf fields.

Your code would need to look more like this instead:

Server side:

int CALLBACK ConditionAcceptFunc(
    LPWSABUF lpCallerId,
    LPWSABUF lpCallerData,
    LPQOS pQos,
    LPQOS lpGQOS,
    LPWSABUF lpCalleeId,
    LPWSABUF lpCalleeData,
    GROUP FAR * g,
    DWORD_PTR dwCallbackData
    )
{
    //printf( "test1\n" );

    //if ((lpCallerData) && (lpCallerData->len >= 8) && (memcmp(lpCallerData->buf, "quyen194", 8) == 0)) 
    if ((lpCallerData) && (lpCallerData->len > 0) && (lpCallerData->buf[0] == 'q')) 
    {
        //if ((lpCalleeData) && (lpCalleeData->len > 0)) {
        //  memcpy( lpCalleeData->buf, "OK", 2 );
        //  lpCalleeData->len = 2;
        //}

        return CF_ACCEPT;
    }
    else
    {
        //printf( "Reject request: \n" );
        //if ((lpCallerData) && (lpCallerData->len > 0)) {
        //  printf( "Buf: %*s", lpCallerData->len, lpCallerData->buf );
        //  printf( "\nLen: %d\n", lpCallerData->len );
        //}
        //if ((lpCalleeData) && (lpCalleeData->len > 0)) {
        //  memcpy( lpCalleeData->buf, "NOT", 3 );
        //  lpCalleeData->len = 3;
        //}

        return CF_REJECT;
    }
}

Client side:

void Connect2Server()
{
    ...

    WSABUF CallerData;
    WSABUF CalleeData;

    char CallerBuf = 'q';
    CallerData.buf = &CallerBuf;
    CallerData.len = 1;

    char CalleeBuf[12] = {0};
    CalleeData.buf = CalleeBuf;
    CalleeData.len = 12;

    printf( "Source: \n" );
    printf( "Buf: %*s", CallerData.len, CallerData.buf );
    printf( "\nLen: %d\n", CallerData.len );

    ...

    ReturnValue = WSAConnect( C_Socket, (SOCKADDR *)&C_Channel, sizeof(C_Channel), &CallerData, &CalleeData, NULL, NULL );

    //printf( "Result: \n" );
    //printf( "Buf: %*s", CalleeData.len, CalleeData.buf );
    //printf( "Len: %d\n", CalleeData.len );

    ...
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top