Winsock问题:收到0长度 [英] winsock question: received 0 length

查看:93
本文介绍了Winsock问题:收到0长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,这可能是一个愚蠢的问题,但是我对Winsock 2.0(尤其是C ++)并不熟悉,所以有人可以帮助我解决这个问题:

我已经编写了c ++控制台应用程序,它使用winsock 2.0.控制台应用程序连接到服务器并获得14字节的响应(一旦连接),然后我尝试发送登录数据,然后我应该从服务器获得响应,但我总是得到0长度,这不是像这样的事.我没有使用任何线程.不确定套接字在C ++中的工作方式.

因此,可能出现的问题很少:我没有收到答案,在此之前我被拒签,或者服务器不了解我的登录信息(这种可能性较小,但很生气).

不幸的是,我没有用于newcamd服务器的代码,只有我翻译的Linux中的客户端代码.

用非常短的代码是这样的:
Connect()
Receive_bytes(获取14个字节)
Send_Login&& Received_bytes!= 0表示登录错误(接收时总是失败)
如果answer_byte ="\ E1",则登录成功
否则answer_byte =" \ E2然后登录失败


在.NET方法中,仅当服务器断开连接时,MySocket.BeginReceive()才会返回0长度,或者将在此方法上等待任何其他答案.对于c ++来说是一样的吗?

我的接收代码(由于我是C ++的新手,所以从某些网络获取的代码作为示例):

Sorry for maybe silly question, but I am not familiar with winsock 2.0 and especially in C++, so could anyone help me with this:

I''ve wrote c++ console application and it uses winsock 2.0. Console application connects to server and gets response with 14 bytes(as soons as it connects), then I am trying to send login data and then I should get a response from server but I always get 0 length which is not suppost to be like that. I am not using any threads. Not sure how socket works in C++.

So there might be few possible issues: I did not received an answer and I get disconected prior this or server did not understood my login (which is less likely but pissible).

Unfortunatelly I have no code for newcamd server, just the code for client in linux which I translated.

In very short code would be something like this:
Connect()
Receive_bytes (getting 14 bytes)
Send_Login && Received_bytes!=0 then is bad login (always fails here on receive)
if answer_byte = "\E1" then login suceeded
else answer_byte= "\E2" then login failed


In .NET method MySocket.BeginReceive() will return 0 length only when server disconnects or will wait on this method for any other answer. Is this same for c++?

My receive code (code taken from some web as an example as I am quite new in C++):

int cNetSocket::Read (unsigned char *data, int len, int to)
{
    string bytes =  mso->ReceiveBytes();
    int mlen = bytes.length();
    if (mlen>0 && mlen<=len) memcpy(data, bytes.c_str(), mlen);
    if (mlen>0 && mlen>len) memcpy(data, bytes.c_str(), len);

    return mlen;
}



经过新的测试后,服务器似乎接受了登录,因此我认为从套接字接收字节数据时存在问题.第一个字节应为零,这可能是字符串的问题.我当前的Socket代码如下所示:



After new testing looks like server accepts login, so I believe that there is a problem in receiving as bytes from socket. The first byte should be zero and this what might be an issue for string. My current Socket code looks like this:

std::string Socket::ReceiveBytes() {
  std::string ret;
  char buf[1024];

  while (1) {
    u_long arg = 0;
    if (ioctlsocket(s_, FIONREAD, &arg) != 0)
      break;

    if (arg == 0)
      break;

    if (arg > 1024) arg = 1024;

    int rv = recv (s_, buf, arg, 0);
    if (rv <= 0) break;

    std::string t;

    t.assign (buf, rv);
    ret += t;
  }

  return ret;
}



谁能帮助我将其转换为未接收到的char数组作为输出?
原始代码来自此Socket示例站点.



Could anyone help me to turn this to unsgined char array as an output?
Original code is taken from this Socket example site.

推荐答案

我希望这可以解决您的问题:
newcamd.c [ ^ ]

至少您可以看到应该发生的事情.

最好的问候
Espen Harlinn
I hope this will solve your problem:
newcamd.c[^]

At least you can see what''s supposed to happen.

Best regards
Espen Harlinn


事实证明,我说对了,它返回0长度而不等待答案,所以我是对的,所以我不得不增加超时的等待时间.

另外,我收到的第一个字节始终为零,这也会导致字符串出现问题,因此我将函数转换为char数组,现在可以正常工作了.

It turns out that I was right saying that it returns 0 length without waiting for an answer, so I had to add waiting time with time out.

Additionaly my first received byte was zero always which would also cause issue with strings so I''ve converted function to char array and now it works.

int Socket::ReceiveBytes(unsigned char *buffer, int len) {
  char buf[1024];
  int ret=0;
  int waitMs=5000;
  memset(buffer,0,len);
  while (1) {
    u_long arg = 0;

    while (waitMs>=0){
        if (ioctlsocket(s_, FIONREAD, &arg) != 0)
          break;

        if (arg == 0) {
            Sleep(200);
            waitMs=waitMs-200;
        }
        else
            break;
    }

    if (arg == 0)
      break;

    if (arg > 1024) arg = 1024;

    int rv = recv (s_, buf, len, 0);
    if (rv <= 0) {
            break;
    }
    else
    {
        //memcpy(buffer,buf, rv-1);
        int c=0;
        for (c=0;c<rv;c++)
            buffer[c]=buf[c];

        ret += rv;
        break;
    }
  }

  return ret;
}


您还可以使用select()函数测试是否有数据包在等待.如果不这样做,则无需调用recv()
You can also use the select() function to test whether you have a packet waiting. If you don''t, then there is no need to call recv()


这篇关于Winsock问题:收到0长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆