2013-04-27 41 views
0

如題,我已經搜查在MSDN中或在互聯網上的一個例子,但我沒有找到任何一個> _ <
他們使用的所有案例WSAConnect(S,sa,sa_len,NULL,NULL,NULL,NULL);
我想使用這些功能(WSAConnect & WSAAccept)與主要簡單權威lpCallerData-> BUF接受
我已經試過從MSDN用於服務器端有關WSAAccept的例子,我對WSAConnect簡單的代碼之前,但它是送花兒給人「 lpCallerData == NULL「
對不起,我的英語不好
提前謝謝您的幫助!如何使用WSAConnect和WSAAccept發送receving初始化數據之前接受請求

我不工作代碼:

服務器端:

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

客戶端:

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

回答

1

lpCallerData是你WSAAccept()回調總是空,因爲TCP/IP不支持交換呼叫者/連接建立期間的被調用者數據。這是WSAConnect()文件中明確提出:

注意連接數據不是由Windows的TCP/IP協議的支持。通過原始套接字僅在ATM(RAWWAN)上支持連接數據。

WSAAccept()文檔還指出:

如果沒有呼叫者識別或呼叫者數據是可用的,相應的參數將是NULL。 許多網絡協議不支持連接時間呼叫者數據

...

的lpCalleeData-> LEN最初包含由服務提供商分配的緩衝區的長度,並通過lpCalleeData-> buf指向的。 值爲零表示不支持將用戶數據傳回給調用者

即使支持,也不能正確管理WSABUF結構。您的服務器不檢查NULL或len溢出,並且您的客戶端代碼沒有爲WSABUF::buf字段分配任何內存。

您的代碼需要看起來更像這個:

服務器端:

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

客戶端:

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

    ... 
} 
+0

非常感謝您!你能否幫我多一個忙?我不知道如何使用TransmitPackets函數和TransmitFile函數> _ <我找不到任何關於它的例子!你能分享我一個簡單的例子,如何在客戶端和服務器端使用它?如果你沒有多少時間,只需按照你的意願寫出簡單的答案:D再次感謝你 – 2013-04-27 12:57:12

相關問題