套接字c ++:recv函数返回-1

时间:2015-06-08 15:53:54

标签: c++ c sockets winsock2 recv

我正在尝试编写与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();
}

至于我的android代码:这里是:

 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但我无法得到解释。

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

2 个答案:

答案 0 :(得分:3)

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

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

编辑0:

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

答案 1 :(得分:1)

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

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

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

Ohwait - Nikloai的编辑首先进入 - 向上投票!