@gibsonman01

Почему при прерывании работы сервера (Ctrl + C) recv не возвращает ошибку?

Использую Windows Sockets 2.

Код сервера:

...
void inputMessage(char* buffer, int size)
{
	printf("Enter message: ");
	
	fgets(buffer, size, stdin);
	buffer[strlen(buffer) - 1] = '\0';  // удалить '\n'
}

int sendMessage(SOCKET ConnectedSocket)
{
	char buffer[MESSAGE_MAXLEN + 1];  // + 1 для '\n'
	int error = 0;

	inputMessage(buffer, MESSAGE_MAXLEN + 1);  // здесь нажмём Ctrl + C

	if (send(ConnectedSocket, buffer, strlen(buffer) + 1, 0) == SOCKET_ERROR)
	{
		error = WSAGetLastError();
		printf("send failed: %d\n", error);
	}

	return error;
}
...


Код клиента:

...
int receiveMessage(SOCKET ClientSocket)
{
	char buffer[MESSAGE_MAXLEN];
	int error = 0;

	puts("Waiting server response...");

	if (recv(ClientSocket, buffer, MESSAGE_MAXLEN, 0) != SOCKET_ERROR)
	{
		// recv не возвращает ошибку
		printf("server response: %s\n", buffer);  // напечатает кракозябры
	}
	else
	{
		error = WSAGetLastError();
		printf("recv failed: %d\n", error);
	}

	return error;
}
...
  • Вопрос задан
  • 313 просмотров
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Возможно серветный сокет закрывается нормально, а recv возвращает 0. Из man recv:
These calls return the number of bytes received, or -1 if an error occurred. The return value will be 0 when the peer has performed an orderly shutdown.

Вообще вы очень лихо печатаете результат из буфера заполненного recv: нет никакой гарантии, что принято будет ровно столько, сколько отправит send, и завершающего символа с кодом 0 может не оказаться в буфере. Правильнее было бы сделать хотя бы так:
ssize_t recvd = recv(ClientSocket, buffer, MESSAGE_MAXLEN, 0);
  if (recvd != SOCKET_ERROR)
  {
    // recv не возвращает ошибку
    printf("server response: %.*s\n", recvd, buffer);  // напечатает только то, что было принято
  }
  else
  {
    error = WSAGetLastError();
    printf("recv failed: %d\n", error);
  }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы