Click here to Skip to main content
15,887,430 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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++):
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;
}


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:

C++
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;
}


Could anyone help me to turn this to unsgined char array as an output?
Original code is taken from this Socket example site.
Posted
Updated 8-Feb-12 2:20am
v4
Comments
Jochen Arndt 8-Feb-12 9:32am    
Why do you use strings with binary data? This will not only fail when there are null bytes, but also with Unicode builds. Just use unsigned char arrays and track the size and count of the buffer.

I hope this will solve your problem:
newcamd.c[^]

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

Best regards
Espen Harlinn
 
Share this answer
 
Comments
Tomazas77 5-Feb-12 16:28pm    
Thanks I'll have a look. I got another similar source.
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.

C++
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;
}
 
Share this answer
 
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()
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900