2011-04-04 200 views
0

我目前正在編寫兩個項目,必須通過TCP彼此進行通信,客戶端必須使用System :: Net :: Sockets ,以及使用C++ winsock的服務器。很長一段時間以來,我一直使用這個可愛的函數來接收winsock中的文本,客戶端首先發送消息長度,然後發送消息。我不想用這個函數在服務器端改變任何東西,但是用.NET我會做任何事情。這是我的嘗試。客戶端/服務器與系統.NET套接字作爲客戶端和服務器上的C++ winsock

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

但我堅持先發送長度則消息

Socket^ s = gcnew Socket(
    AddressFamily::InterNetwork, 
    SocketType::Stream, 
    ProtocolType::Tcp 
); 
s->Connect(server, 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); 

回答

2

有兩個問題,我簡要閱讀後看到:

  1. 你要發送的字符串長度as一個字符串,但服務器正在以二進制形式讀取它。
  2. 服務器假定recv將始終讀取請求的字節數。這是錯誤的; recv可能會返回0(如果另一方已正常關閉連接),範圍[1,len](如果某些數據已成功接收)或SOCKET_ERROR(如果有錯誤)範圍內的任何值。