如何在接受请求之前使用WSAConnect和WSAAccept发送接收的init数据

作为标题,我在MSDN或互联网上search了一个例子,但我没有find任何一个> _ <
所有使用WSAConnect的情况(S,sa,sa_len, NULL,NULL,NULL,NULL );
我想使用这些函数(WSAConnect&WSAAccept)作为一个简单的权限,在接受前使用lpCallerData-> buf中的键
我已经尝试了从msdn的WSAAccept为服务器端的示例和我简单的代码有关WSAConnect,但它总是“lpCallerData == NULL”
对不起,我的英语不好
提前感谢您的帮助!

我不工作的代码:

服务器端:

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

lpCallerDataWSAAccept()回调中始终为NULL,因为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 ); ... }