【问题标题】:Socket c++: recv function returns -1套接字c ++:recv函数返回-1
【发布时间】:2015-06-08 15:53:54
【问题描述】:

我正在尝试编写一个与 Windows 服务器通信的简单 android 客户端。 我正在使用套接字来实现这一点,到目前为止,我正在使用 Linux 机器(android 客户端和 linux 服务器)测试所有内容。到目前为止,一切正常。现在我正在尝试在 Windows(服务器)上设置它,我当然注意到我必须稍微更改我的代码(如果不只是包含 ^^')。 无论如何,我的问题是我的 recv 函数返回 -1 虽然它应该读取一些东西,但由于某种原因它没有。

以下是我如何使用我的 recv 函数(编辑:现在是整个服务器代码):

int tcp_server::start_listening()
{

    WORD wVersionRequested;
    WSADATA wsaData;
    int wsaerr;
    wVersionRequested = MAKEWORD(2, 2);
    wsaerr = WSAStartup(wVersionRequested, &wsaData);
    if (wsaerr != 0)
    {
        printf("Server: The Winsock dll not found!\n");
        WSACleanup();
        return 0;
    }

   else
    {
        printf("Server: The Winsock2 dll found \n");
    }

    sSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(sSock == INVALID_SOCKET)
    {
        printf("Server: Error initializing socket!n");
        WSACleanup();
        return 0;
    }


    sockaddr_in service,client ;
    service.sin_family = AF_INET;
    service.sin_port = htons(port);
    service.sin_addr.s_addr = INADDR_ANY;


   if(bind(sSock,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
   {
       printf("Server: Error binding socket to portn");
       WSACleanup();
       return 0;
   }

   /* wait for incoming connections */
   if(listen(sSock,10)==SOCKET_ERROR)
       printf("listen(): Error listening on socket %d\n", WSAGetLastError());
   else
   {
      printf("Server: Waiting for connections...\n");
   }

   /* accept connections */
   AcceptSocket;
   printf("Server: Waiting for a client to connect...\n");
   AcceptSocket = accept(sSock, NULL, NULL);
   if (AcceptSocket == INVALID_SOCKET) {
       wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
       closesocket(sSock);
       WSACleanup();
       return 1;
   } else {
       wprintf(L"Client connected.\n");
       acceptConns();
   }

   closesocket(sSock);
   return 0;
}
int tcp_server::acceptConns()
{
    sockaddr_in from;
    bool infinite = true ;
    int fromlen=sizeof(from);
    int readsize;
    char* message;
    char* clientmessage = "\0";
    string smatrix ;
    int ind ;
    string tok;
    int i = 0 ;
    int bytesSent ;

    float matrix[16] ;
    while( (readsize = recv(AcceptSocket, clientmessage, 2000, 0))!= 0 ){
        message = "ack";
        cout << "Writing ACK" << endl ;
        smatrix = clientmessage ;
        std::stringstream ss(smatrix);

        cout << smatrix << endl ;
        while(getline(ss, tok, ',') && i < 16 ){
            matrix[i] = static_cast<float>(::atof(tok.c_str()));
            i++ ;
        }
        i = 0 ;
        Sleep(1000);
    }
    if(readsize == 0 ){
        cerr << "client disconnected" << endl ;
    }
    cout << "Socket closed" << endl ;
    closesocket(sSock);
    WSACleanup();
}

至于我的安卓代码:这里是:

 while(closeConnection == false) {
        if (connected == true && matrixupdated == true && this.hasMatrixChanged()){
            try {
                //= new BufferedReader(new InputStreamReader(java.lang.System.in));
                DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
                String sentence = this.getStringFromMatrix();
                outToServer.writeBytes(sentence + "\n");
                outToServer.flush();
                inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                System.arraycopy(matrix, 0, previousMatrix, 0, 16);
                inFromServer.read(serverMsg);
                if(serverMsg.equals("ack") == true){
                    this.serverHasInput = false ;
                    Log.e("ACK", "ACK");
                    inFromServer.read(serverMsg);       //Wait for the "ok" message from server
                    if(serverMsg.equals("ok") == false){
                        Log.e("ERROR IN COM W/ SERV"," DID NOT RECEIVE OK");
                    }
                }
                else{
                    this.serverHasInput = true ;
                }
                //Log.d("SERVERMSG", "DONE WAITING");

            }catch (Exception e) {
                Log.e("ClientActivity", "S: Error", e);
            }
            this.matrixupdated = false ;
        }

    }
    try {
        outToServer.flush();
        outToServer.close();
        inFromServer.close();
        clientSocket.close();
    }

最后不幸的是我在控制台中得到的输出

客户端断开

我猜这可能是一些非常愚蠢的东西,但我一直试图在 MS 网站和 recv 的文档上查看为什么它会给我 -1 但我无法得到解释。

提前感谢您提供的帮助:)。

【问题讨论】:

  • OK,当系统调用失败时,WSAGetLastError() 的结果是什么?
  • '试图在 MS 网站和 recv 的文档上查看为什么它会给我 -1 但我无法得到解释' 真的??? MSDN:如果没有发生错误,recv 返回接收到的字节数,buf 参数指向的缓冲区将包含接收到的数据。如果连接已正常关闭,则返回值为零。否则,返回 SOCKET_ERROR 的值,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。'
  • 我投票结束这个问题,因为 OP 没有阅读失败的系统调用的 MSDN 文档。
  • 另外,你的缓冲区 'char* clientmessage = "\0";'是一个字符串文字,它太短而不能容纳 2000 个字符,是只读的,会导致 recv() 失败。
  • 服务器代码中的这一行 cout &lt;&lt; recv(sSock, clientmessage, 2000, 0) &lt;&lt; endl ; 可能会读取所有内容,而不会为下一条语句 while( (readsize = recv(sSock, clientmessage, 2000, 0))!= 0 ) 留下任何内容。在进入 while 循环时,如果没有任何东西可以接收,readsize 将被设置为 0,因此client disconnected 输出。

标签: c++ c sockets winsock2 recv


【解决方案1】:

C++ 代码中的许多错误 - 例如 if (bytesSent = 0),这是一个将结果转换为布尔值的赋值,因此总是返回 false。您不会注意从 TCP 套接字读取的字节数,假设您在发送它时收到一条完整的消息 - 这是错误的,因为您可能正在读取部分消息、多于一条消息或介于两者之间的任何消息 - 这是一个原始字节流

检查系统调用显式返回的-1,然后检查errno(3) 的值,例如strerror(3) 函数以找出问题所在。

编辑 0:

您正在尝试使用侦听套接字 sSock 进行数据传输 - 错误 - 它仅用于接受客户端连接请求。使用AcceptedSocket,即从accept() 返回的那个。它是与客户端的连接。

【讨论】:

【解决方案2】:

您应该读取/写入的客户端套接字是由 Accept() 调用返回的“AcceptSocket”,而不是“sSock”服务器套接字!

要么将 AcceptSocket 的声明移动到成员 var,将其传递给 'acceptConns();'作为参数或启动一个线程来运行 acceptConns,将 AcceptSocket 作为 void* 参数传递给 pthread_create,(或其他)。

我认为,即使在您发布接受代码之前,Remy 和我都强烈怀疑这是您的问题:)

Ohwait - Nikloai 的编辑首先获得 - 为他点赞!

【讨论】:

  • 确实你说得对,它确实部分解决了我的问题。现在仍然必须弄清楚为什么我从客户端收到一条空消息(我确定已经发送了一些东西,所以它确实再次来自服务器^^'):)
  • 最后如上所述并没有解决我的问题,因为我仍然小于 0
  • 你修复了'clientmessage = "\0";'问题?
  • Mebbe,您应该发布一个新问题,其中包含您的最新代码、新问题和调试结果。编辑您的原始问题并不能为未来的 SO 用户提供一个很好的问答资源 - 它会迫使他们努力进行编辑并让他们感到困惑:(
  • 该死,当回到我的代码的以前版本时,我没有注意到固定的 client_message 不再固定的事实。无论如何,非常感谢您的帮助。所以我猜你和尼古拉都是对的,有什么方法可以给你两个学分吗? :)
猜你喜欢
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
  • 2020-03-12
  • 1970-01-01
  • 2013-07-31
相关资源
最近更新 更多