В настоящее время я изучаю C++ и пытаюсь понять сокеты. Я делал сокеты раньше на языках высокого уровня в C# и Java, но имел проблемы на C++.Отправка и получение данных в сокете в C++
Я рассмотрел пример на https://msdn.microsoft.com/en-us/library/windows/desktop/ms737593(v=vs.85).aspx.
Код, который у меня есть, очень много работает, за исключением того, что я не уверен. Когда я писал другие приложения для сокетов, я обычно не получаю ответ до тех пор, пока не будет получен новый символ строки.
Я подумал, что возможно, C++ добавляет 1 символ и добавляется в буфер, поэтому, когда я закрываю сокет, буфер будет содержать все, что было получено, но оно, как представляется, является шестнадцатеричным значением, но hex в конвертере ascii, похоже, печатает тарабарщину вместо данных сокета.
Ниже мой код
const int DEFAULT_BUF_LEN = 525;
InitialiseLibrary initLibrary("tunnel.conf");
if (initLibrary.initialise(0))
{
cout << "Failed to initialise library" << endl;
}
BitsLibrary bitsLibrary;
StaticSettings staticSettings(&bitsLibrary, "tunnel.conf");
//Open a socket connection
WSAData wsaData;
int iResult;
SOCKET listenSocket = INVALID_SOCKET;
SOCKET clientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvBuf[DEFAULT_BUF_LEN];
int recBufLen = DEFAULT_BUF_LEN;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
{
cout << "WSAStartup Failed with error: " << iResult << endl;
return EXIT_FAILURE;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = getaddrinfo(NULL, "500", &hints, &result);
if (iResult != 0)
{
cout << "getaddrinfo failed with error: " << iResult << endl;
return EXIT_FAILURE;
}
listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (listenSocket == INVALID_SOCKET)
{
cout << "Socket failed with error: " << WSAGetLastError() << endl;
freeaddrinfo(result);
WSACleanup();
return EXIT_FAILURE;
}
iResult = ::bind(listenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult != 0)
{
cout << "bind failed with error: " << iResult << endl;
FreeAddrInfo(result);
closesocket(listenSocket);
WSACleanup();
return EXIT_FAILURE;
}
freeaddrinfo(result);
iResult = listen(listenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR)
{
cout << "Listen failed with error: " << WSAGetLastError() << endl;
closesocket(listenSocket);
WSACleanup();
return EXIT_SUCCESS;
}
sockaddr_in clientAddr;
socklen_t sin_size = sizeof(struct sockaddr_in);
clientSocket = accept(listenSocket, (struct sockaddr*)&clientAddr, &sin_size);
send(clientSocket, "welcome", string("welcome").length(),0);
if (clientSocket == INVALID_SOCKET)
{
cout << "accept failed with error: " << WSAGetLastError() << endl;
closesocket(listenSocket);
WSACleanup();
return EXIT_FAILURE;
}
closesocket(listenSocket);
do {
iResult = recv(clientSocket, recvBuf, recBufLen, 0);
if (iResult > 0)
{
cout << "Bytes received: " << iResult << endl;
cout << "Received: " << recvBuf << endl;
iSendResult = send(clientSocket, recvBuf, iResult, 0);
if (iSendResult == SOCKET_ERROR)
{
cout << "send failed with error: " << WSAGetLastError() << endl;
closesocket(clientSocket);
WSACleanup();
return EXIT_FAILURE;
}
cout << "Bytes sent " << iSendResult << endl;
}
else if (iResult == 0)
{
cout << "Connection closing" << endl;
}
else
{
cout << "Recv failed with error: " << WSAGetLastError() << endl;
closesocket(clientSocket);
WSACleanup();
return EXIT_FAILURE;
}
} while (iResult > 0);
iResult = shutdown(clientSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
cout << "shutdown failed with error: " << WSAGetLastError() << endl;
closesocket(clientSocket);
WSACleanup();
return EXIT_FAILURE;
}
closesocket(clientSocket);
WSACleanup();
cout << "Message was: " << recvBuf << endl;
return EXIT_SUCCESS;
Если я не ошибаюсь, если я делаю это в C# и подключение через телнет к моему гнезду я мог отправить Hello
но приложение никогда ничего не делал бы, пока я отправлен \r\n
или буфер был заполнен.
Однако в моей C++ приложение, как только я вхожу H
мое приложение немедленно реагирует распечатывает recvBuf, который просто содержит H
плюс груз пустых символов (показывает, как квадраты в ЦМД), который я предполагаю, что это пустая части буфера массива и отправляет ответ.
А я думал, что это может быть так, поэтому в C++ нет ничего, что сделало бы это для меня, если бы я хотел, чтобы recv возвращался только к новым строкам, мне нужно было бы это сам кодировать, нет библиотек или чего-то еще часть C++, которая сделала бы это – Boardy
@Boardy Существует около бесконечных библиотек, которые делают это (большинство из них плохие, но все же). – deviantfan
ха-ха. Хорошо, привет. Спасибо за вашу помощь – Boardy