WSASocket()的定义

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WSASocket()的定义相关的知识,希望对你有一定的参考价值。

参考技术A

SOCKET WSASocket (  int af,   int type,   int protocol,   LPWSAPROTOCOL_INFO lpProtocolInfo,   GROUP g,   DWORD dwFlags   );
参数说明:
af:[in]一个地址族规范。目前仅支持AF_INET格式,亦即ARPA Internet地址格式。
type:新套接口的类型描述。
protocol:套接口使用的特定协议,如果调用者不愿指定协议则定为0。
lpProtocolInfo:一个指向PROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。如果本参数非零,则前三个参数(af, type, protocol)被忽略。
g:保留给未来使用的套接字组。套接口组的标识符。
iFlags:套接口属性描述。

在我的代码中出现这个“10038 wsa socket”错误

【中文标题】在我的代码中出现这个“10038 wsa socket”错误【英文标题】:Getting this "10038 wsa socket" error in my code 【发布时间】:2015-07-13 18:10:53 【问题描述】:

我目前正在尝试实现一个类来创建和使用 TCP 连接。

(我是 C++ 的新手,所以我可能忘记了一些明显的东西,即使我一直在认真检查我的代码)

请注意,稍后我将实现第二个类来处理新连接,因此代码的某些部分不完整/排列整齐,我希望这不会在您尝试理解它时打扰您。

这是我的问题:

服务器和客户端似乎都工作正常(我一直在检查我的监听、绑定、连接功能:没有错误)而且我显然能够与客户端发送数据但是当我尝试读取它时从服务器,我收到 WSA 错误 10038(这意味着我正在无效套接字上执行 recv())。我已经查了几天了,似乎找不到我的错误。除了代码中的测试外,我还使用“netstat -an -p tcp”检查连接状态,一切正常,但服务器收不到数据。

注意:我使用的是 Visual Studio 6(是的,它很旧,但它是强制性的......)和 winsock,而不是 winsock2。

如果我忘记了什么就问吧,我会尽量做到完整,但忘记某些东西并非不可能。

这是我的源代码,我试图将其简化,但我担心错误可能几乎无处不在:

CmTcpTransport.cpp

/**
Initializes the TCP connection (socket) in CLIENT or SERVER mode.
It does not connect yet.

@param strIPAddress: IP Address to reach
       nPort: Port to connect to
       hSocket: client Socket if SERVER mode
       nTcpMode: mode for this connexion SERVER(1) or CLIENT(2)      
       
@return an int to get the exit point of the function
*/
int CmTcpTransport::initialize(std::string strIPAddress, unsigned int nPort,         SOCKET hSocket, int nTcpMode)

m_nTcpMode = nTcpMode; 

cout << "Creating TCP connexion..." << endl << endl;

if (nTcpMode == 1) // SERVER


    serveraddr.sin_family = AF_INET; // address family Internet
    serveraddr.sin_port = htons (nPort); // Port to connect on
    serveraddr.sin_addr.s_addr = inet_addr (strIPAddress.c_str()); // Target IP

    cout << "SERVER: Retrieving socket information..." << endl; 
            
    if (hSocket == INVALID_SOCKET)
    
        return 102; // The received socket is invalid
        cout << "SERVER: Socket creation failed" << endl;
      

    serverSocket = hSocket;

    cout << "SERVER: Listening socket received" << endl;

    if (bind(serverSocket, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == SOCKET_ERROR)
    
        return 103; // Couldn't bind
        cout << "SERVER: Socket binding failed" << endl;
       
    else 
        cout << "SERVER: Binding successful" << endl;
    

    if (listen(serverSocket, 1) == SOCKET_ERROR)
    
        return 103; // Couldn't listen
        cout << "SERVER: Socket listening failed" << endl;
    
    else 
        cout << "SERVER: Listening to socket" << endl;
    


else // CLIENT

    serveraddr.sin_family = AF_INET; // address family Internet
    serveraddr.sin_port = htons (nPort); // Port to connect on
    serveraddr.sin_addr.s_addr = inet_addr (strIPAddress.c_str()); // Target IP

    cout << "CLIENT: Creating client socket..." << endl;

    clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // CREATE CLIENT SOCKET

    if (clientSocket == INVALID_SOCKET)
    
        return 104; // Couldn't create the socket
        cout << "CLIENT: Socket creation failed" << endl;
      

    cout << "CLIENT: Client socket created" << endl;




cout << "Initialization succeeded." << endl << endl << endl;
return 105;


/**
Creates the connexion to TCP

@param none        
@return an int to get the exit point of the function
*/
int CmTcpTransport::connectTcp()



if (m_nTcpMode == 1) // SERVER

    cout << "Waiting for connexion..." << endl;
    int clientLen(0);
    clientLen = sizeof(clientaddr);
    

    if ((clientSocket = accept(serverSocket, (SOCKADDR *)&clientaddr, &clientLen) == INVALID_SOCKET))
    
        cout << "SERVER: Connexion failed." << endl;
        return 202;; // Couldn't listen
    
    else 
        cout << "SERVER: Connexion established." << endl << endl << endl;
        if (clientSocket == SOCKET_ERROR) 
        
            printf("socket became invalid after connexion:: %d\n", WSAGetLastError());
        
        else 
                cout << "SOCKET STILL VALID AND WORKING AFTER CONNEXION" << endl;
        
        return 201;
    
    


else // CLIENT

    cout << "Connecting..." << endl;
    if (connect(clientSocket, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) == SOCKET_ERROR)
    
        cout << "CLIENT: Connexion failed." << endl << endl << endl;
        return 202;; // Couldn't connect
    
    else 
    
        cout << "CLIENT: Connexion to server succeeded." << endl << endl <<         endl;
    
    return 203;



/**
Receives a buffer of bytes from the TCP

@param buffer: buffer to store the data
       bufLen: size of the buffer
       
@return nbChar: the result of the recv function
if no error occurs, recv returns the number of bytes received
else, it returns a value of SOCKET_ERROR
*/
int CmTcpTransport::recvTcp(char *buffer, int bufLen)

if (clientSocket == SOCKET_ERROR) 
        
            printf("socket became invalid before receive:: %d\n",  WSAGetLastError());
        
        else 
                cout << "SOCKET STILL VALID AND WORKING BEFORE RECEIVE" <<         endl;
        
        
int nbChar = recv(clientSocket, buffer, bufLen, 0);
if (nbChar == SOCKET_ERROR)

    printf("recv failed: %d\n", WSAGetLastError());
    cout << "No data received." << endl << endl << endl;
    return nbChar;

else 
    buffer[nbChar]=0; // Gestion de la taille du buffer
    cout << "Data received: " << buffer << endl << endl << endl;
    return nbChar;


/**
Sends a buffer of bytes to the TCP

@param buffer: buffer containing the data
       bufLen: size of the buffer
       
@return nbChar: the result of the send function
if no error occurs, recv returns the number of bytes sent
else, it returns a value of SOCKET_ERROR
*/
int CmTcpTransport::sendTcp(char *buffer, int bufLen)


int nbChar = send(clientSocket, buffer, bufLen,0);
if (nbChar == SOCKET_ERROR)

    
    cout << "No data sent." << endl << endl << endl;
    return nbChar;

else 
    cout << "Data sent: " << buffer << endl << endl << endl;
    return nbChar;


服务器 main.cpp

int main(int argc, char* argv[])

// ----------------------- WINSOCK ----------------------------

cout << "Initializing winsock library..." << endl;

// Start up Winsock
WSADATA wsadata;

int error = WSAStartup(0x101, &wsadata);

// Error ?
if (error) 0;

// Try Winsock Version ?
if (wsadata.wVersion != 0x101)

    WSACleanup(); // Clean up Winsock
    return 101;


cout << "Initialization successful" << endl << endl << endl;


// ----------------------- SERVER ---------------------------

char buffer[3000];

int testRecv; // return of the recv function

cout << "SERVER" << endl << endl << endl;

// Simulate the activity of the TcpListener transfering a listening Socket for the client connexion
SOCKET testSocket;
testSocket = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP); 

// Creating a new TCP transport
CmTcpTransport server;

// Initialize and connect the TCP transport
server.initialize("127.0.0.1", 10000, testSocket, TTCP_MODE_SERVER);

server.connectTcp();

// Try to receive data
testRecv = server.recvTcp(buffer, sizeof(buffer));

cout << testRecv << endl;

// Disconnect
server.disconnectTcp();


return 0;

客户端 main.cpp

int main(int argc, char* argv[])


// ----------------------- WINSOCK ----------------------------

cout << "Initializing winsock library..." << endl;

// Start up Winsock
WSADATA wsadata;

int error = WSAStartup(0x0202, &wsadata);

// Error ?
if (error) 0;

// Try Winsock Version ?
if (wsadata.wVersion != 0x0202)

    WSACleanup(); // Clean up Winsock
    return 101;


cout << "Initialization successful" << endl << endl << endl;


// ----------------------- CLIENT ---------------------------

char buffer[10000];

cout << "CLIENT" << endl << endl << endl;

// this Socket won't be used as the TCP transport is in client mode
SOCKET test;
test = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);

// Create, initialize and connect the client TCP transport
CmTcpTransport client;

client.initialize("127.0.0.1", 10000, test, TTCP_MODE_CLIENT);

client.connectTcp();

// Copy the data in the buffer and send it
strcpy(buffer, "Test donnees");

client.sendTcp(buffer, sizeof(buffer));

client.disconnectTcp();

return 0;

以下是我同时运行两个电源时的控制台屏幕截图:

http://www.hostingpics.net/viewer.php?id=892752Consoles.jpg

感谢您的帮助,我意识到这需要阅读/处理很多内容,我感谢您的努力!

【问题讨论】:

这通常是调试器的用途,而不是关于 SO 的问题。 小编辑:我已经更正了这样一个事实,即我的“返回”在错误的情况下是在我的“cout 错误......”之前,这是我的代码的一个旧但工作版本。通过工作,我的意思是我在 recv() 上遇到错误 10038。 【参考方案1】:

我认为您使用不正确的大括号使 accept 上的新 sock-id 无效:

if ((clientSocket = accept(serverSocket, (SOCKADDR *)&amp;clientaddr, &amp;clientLen) == INVALID_SOCKET))

尝试将其更改为:

if ((clientSocket = accept(serverSocket, (SOCKADDR *)&amp;clientaddr, &amp;clientLen)) == INVALID_SOCKET)

【讨论】:

谢谢!有效。我确信这很荒谬,我想这是一个很好的教训。 谢谢,Prabhu,我也遇到了同样的问题!

以上是关于WSASocket()的定义的主要内容,如果未能解决你的问题,请参考以下文章

WSASocket()的例子

WSASocket()函数使用解析

WSASocket() 应该与 IOCP 一起使用吗?

在我的代码中出现这个“10038 wsa socket”错误

winSockets编程socket函数

如何将socket设置为非阻塞模式