简体   繁体   English

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

[英]Socket c++: recv function returns -1

I'm trying to code a simple android client communicating with a windows server. 我正在尝试编写与Windows服务器通信的简单android客户端代码。 I'm using sockets to achieve that and up to now, I was testing everything with a Linux machine (android client and linux server). 我正在使用套接字来实现这一目标,直到现在,我都在使用Linux机器(android客户端和linux服务器)进行测试。 So far, everything was working. 到目前为止,一切正常。 Now i'm trying to set it up on windows (the server) and I have of course noticed that I had to change my code a little (if not just the include ^^'). 现在,我正在尝试在Windows(服务器)上进行设置,我当然注意到我必须稍稍更改代码(如果不只是include ^^')。 Anyway, my problem is that my recv functions returns -1 while it should read something but it doesn't for some reason. 无论如何,我的问题是我的recv函数返回-1,尽管它应该读取某些内容,但是由于某种原因而没有。

Below is how I use my recv function (EDIT: the whole server code now): 下面是我如何使用我的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();
}

As for my android code: here it is: 至于我的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();
    }

Finally the output I get in the console is unfortunately 最后,不幸的是我在控制台中得到的输出

client disconnected 客户端断开连接

I'm guessing this is probably some really dumb stuff, but i've been trying to see on MS website and the documentation of recv why it would give me -1 but I can't get my hands on a explanation. 我猜这可能是一些非常愚蠢的东西,但是我一直在尝试在MS网站和recv的文档上看到它为什么会给我-1的信息,但我无法获得解释。

Thanks in advance for the help provided :). 在此先感谢您提供的帮助:)。

Many errors in the C++ code - like if (bytesSent = 0) , which is an assignment with result cast to boolean, so always returning false . C ++代码中的许多错误-如if (bytesSent = 0) ,这是一个将结果if (bytesSent = 0)为boolean的赋值,因此始终返回false You don't pay attention to number of bytes read from a TCP socket, assuming that you receive one complete message as you sent it - this is wrong since you might be reading a partial message, more then one message, or anything in between - it is a raw byte stream . 假设您在发送时收到一条完整的消息,则无需注意从TCP套接字读取的字节数-这是错误的,因为您可能正在读取部分消息,多于一条消息或两者之间的任何消息- 这是一个原始字节流

Check for -1 returned from system calls explicitly, and then examine the value of errno(3) , with say, strerror(3) function to figure out what went wrong. 检查从系统调用中显式返回的-1 ,然后使用strerror(3)函数检查errno(3)的值,以找出问题所在。

Edit 0: 编辑0:

You are trying to use the listening socket sSock for data transfer - wrong - it is only there for accepting client connection requests. 您正在尝试使用侦听套接字sSock进行数据传输-错误-它仅用于接受客户端连接请求。 Use AcceptedSocket , the one returned from accept() . 使用AcceptedSocket ,这是从accept()返回的值。 It is the connection to the client. 它是与客户端的连接。

The client socket that you should be reading/writing to is the 'AcceptSocket' that is returned by the Accept() call, Not the 'sSock' server socket! 您应该读取/写入的客户端套接字是由Accept()调用返回的'AcceptSocket',而不是'sSock'服务器套接字!

Either move the declaration of AcceptSocket to a member var, pass it to 'acceptConns();' 将AcceptSocket的声明移到成员var,将其传递给'acceptConns();' as a parameter or start a thread to run acceptConns, passing the AcceptSocket as the void* parameter to pthread_create, (or whatever). 作为参数或启动线程以运行acceptConns,将AcceptSocket作为void *参数传递给pthread_create(或其他)。

I think that both Remy and I strongly suspected that this was your problem even before you posted the Accept code:) 我认为雷米和我都强烈怀疑这是您的问题,甚至在您发布接受代码之前:)

Ohwait - Nikloai's edit got in first - upvote him! Ohwait-Nikloai的编辑首先进入-支持他!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM