Не удается получить ответ при использовании сокета в C++.NET
Я написал две программы, одну как сервер, а другую как клиент. Сервер написан на стандартном C++ с использованием WinSock2.h
, Это простой эхо- сервер, который означает, что сервер отвечает клиенту на то, что он получает. Я использовал новый поток для каждого подключения клиента, и в каждом потоке:
Socket* s = (Socket*) a;
while (1) {
std::string r = s->ReceiveLine()
if (r.empty()) {
break;
}
s->SendLine(r);
}
delete s;
return 0;
Socket
это класс отсюда. Сервер работает нормально, и я проверил его, используя telnet
, это работает хорошо.
Затем я написал клиент, используя C++.NET (или C++/CLI), TcpClient
используется для отправки и получения сообщения с сервера. Код похож на:
String^ request = "test";
TcpClient ^ client = gcnew TcpClient(server, port);
array<Byte> ^ data = Encoding::ASCII->GetBytes(request);
NetworkStream ^ stream = client->GetStream();
stream->Write(data, 0, data->Length);
data = gcnew array<Byte>(256);
String ^ response = String::Empty;
int bytes = stream->Read(data, 0, data->Length);
response = Encoding::ASCII->GetString(data, 0, bytes);
client->Close();
Когда я запускаю клиент и пытаюсь показать ответное сообщение в моей форме, программа останавливается в строке int bytes = stream->Read(data, 0, data->Length);
и не может получить ответ. Сервер работает и не имеет ничего общего с сетью, так как все они работают на одном компьютере.
Я думаю, причина в том, что сервер данных отвечает меньше, чем data->Length
, Итак Read
Метод ожидает больше данных. Это правильно? Как мне решить эту проблему?
редактировать
Я думаю, что я решил проблему... Есть еще два метода в Socket
учебный класс, ReceiveBytes
а также SendBytes
и эти два метода не будут удалять неиспользуемое пространство в массиве байтов. Таким образом, длина данных, возвращаемых с сервера, будет соответствовать длине данных от клиента, поэтому Read
Метод не будет ждать получения новых данных.
1 ответ
std::string Socket::ReceiveLine() {
std::string ret;
while (1) {
char r;
switch(recv(s_, &r, 1, 0)) {
case 0: // not connected anymore;
// ... but last line sent
// might not end in \n,
// so return ret anyway.
return ret;
case -1:
return "";
// if (errno == EAGAIN) {
// return ret;
// } else {
// // not connected anymore
// return "";
// }
}
ret += r;
if (r == '\n') return ret;
}
}
Я полагаю, что функция receiveline сервера ожидает ввода ключа '\n'.
просто попробуйте с помощью строки "test\n".
String^ request = "test\n";
// other codes....