开发者

Client/Server with System .NET sockets as client and c++ winsock on the server

I am currently writing two projects that have to communicate with each other over TCP, with the client having to be implemented using System::Net::Sockets, and the server using c++ winsock. For a long time, I have been using this lovely function to receive text in winsock, where the client sends the message length first and then the message. I don't want to have to change anything on the server side with this function, but with the .NET I will do anything. This is my attempt.

bool WinSockObject::receiveText(std::string &out)
{
    //Create a temporary buffer to work with
    char buf[4096];
    //Stores textLength of incoming data
    long textLength = 0;
    //Receive the textLength that was sent first
    _result = ::recv(
        _socket, //socket we are receiving on
        reinterpret_cast< char *>(&textLength), //the length of the incoming text
        sizeof(textLength), //number of bytes
        0 //no additional flags necessary
    );
    //Make sure we got the text length
    if (_result == SOCKET_ERROR)
    {
        set_error("Unable to receive text length.");
        return false;
    }
    //Convert the textLength back to host bytes
    textLength = ::ntohl(textLength);
    //Receive the actual message
    _result = ::recv(
        _socket, //socket we are receiving on
        buf, //the input buffer
        textLength, //text length
        0 //no additional flags are necessary
    );
    //Make sure we got the actual message
    if (_result == SOCKET_ERROR)
    {
        set_error("Unable to receive text.");
        return false;
    }
    //Manually terminate the buffer
    buf[textLength] = '\0';
    //Copy the buffer to the output string
    out.append(buf);
    return true;
}

But I am stuck sending the length first then the message

Socket^ s = gcnew Socket(
    AddressFamily::InterNetwork,
    SocketType::Stream,
    ProtocolType::Tcp
);
s->Connect(se开发者_JAVA百科rver, port); //message to send
String^ howdy = "howdy";
int strLength = howdy->Length; //length of message
String^ length = strLength.ToString(); //convert it to String
//get the bytes
array<Byte>^msgLength = Encoding::ASCII->GetBytes(length);
//send the message length
int bytes = s->Send(msgLength);
//send the actual message
array<Byte>^msg = Encoding::ASCII->GetBytes(howdy);
bytes = s->Send(msg);


There are two problems that I see after a brief reading:

  1. You're sending the string length as a string, but the server is reading it as binary.
  2. The server is assuming that recv will always read the number of bytes requested. This is wrong; recv may return 0 (if the other side has closed the connection gracefully), any value in the range [1, len] (if some data was received successfully), or SOCKET_ERROR (if there was an error).
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜