Manujaya Premathilaka Ответов: 0

Почему функция " read()" в сокетах возвращает ошибку "плохой файловый дескриптор"?


Я новичок в программировании сокетов. Я использую eclipse ide на языке C++. Я попробовал простую клиент-серверную программу, и она дает мне ошибку в методе read() серверной программы.

Это моя серверная программа:
void Server2::createSocket(){
	#ifdef WIN32
	// Initialize Winsock
	int iResult;
	WSADATA wsaData;
	iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (iResult != 0) {
		std::cout << "WSAStartup failed: " << iResult << std::endl;

	}
	#endif

	sockfd = socket(AF_INET, SOCK_STREAM, 0);

	if(sockfd < 0){
		int err = WSAGetLastError();
		cout << "Create socket failed with error " << err << endl;
		exit(EXIT_FAILURE);
	}

}

void Server2::clearAdrressStructure(){

	bzero((char*)&serv_addr, sizeof(serv_addr));

}

void Server2::bindSocket(){
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);

	if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
		int err = WSAGetLastError();
		cout << "Bind failed with error " << err << endl;
		exit(EXIT_FAILURE);
	}

}

void Server2::listenConnection(){

	int a = listen(sockfd, 5);

	if(a < 0){
		int err = WSAGetLastError();
		cout << "Listen failed with error " << err << endl;
		exit(EXIT_FAILURE);
	}

}

void Server2::acceptConnection(){
	clilen = sizeof(clien_addr);

	newsockfd = accept(sockfd, (struct sockaddr *)&clien_addr, &clilen);

	if(newsockfd < 0){
		int err = WSAGetLastError();
		cout << "Accept failed with error " << err << endl;
		exit(EXIT_FAILURE);
	}

	cout << "Server got connection from " << inet_ntoa(clien_addr.sin_addr) << " port " << ntohs(clien_addr.sin_port) << endl;
}

void Server2::sendMessage(){

	if(send(newsockfd, "Hello, World!\n", 13, 0) < 0){
		int err = WSAGetLastError();
		cout << "Send failed with error " << err << endl;
		perror("Sending failed");
		exit(EXIT_FAILURE);
	}
	bzero(buffer, 256);

}

void Server2::readSocket(){

	if(read(newsockfd, buffer, sizeof(buffer)) < 0){
		int err = WSAGetLastError();
		cout << "Read failed with error " << err << endl;
		perror("Reading failed");
		exit(EXIT_FAILURE);
	}

	cout << "MESSAGE: " << buffer << endl;
}


Это порядок вызова методов:
<pre>int main(){

	Server2 server;

	server.createSocket();
	server.clearAdrressStructure();
	server.bindSocket();
	server.listenConnection();
	server.acceptConnection();
	server.sendMessage();
	server.readSocket();

	close(server.newsockfd);
	close(server.sockfd);

	return 0;
}


Извините за публикацию всего кода. Я делаю это потому, что понятия не имею, делаю ли я что-то неправильно в других методах, хотя ошибка возникает в методе readSocket (). Спасибо Вам за ваше драгоценное время!

Что я уже пробовал:

Я попробовал изменить номера портов и использовать метод recv() вместо read()

Shao Voon Wong

Ваш код выглядит правильно через send/recv, который должен использоваться вместе. Я предполагаю, что ваш клиент разбился еще до того, как он смог отправить свое сообщение на сервер, когда он отобразил "Привет, Мир!" потому что эта строка не завершается нулем. Попробуйте отправить код ниже.

if(send(newsockfd, "Hello, World!\0", 14, 0) < 0){

Richard MacCutchan

Одна из проблем с вашим кодом заключается в том, что все ваши функции не принимают никаких параметров и не возвращают никаких результатов, поэтому трудно понять, какой сокет какой. И вы действительно должны отделить серверный код от клиентского, чтобы было ясно, какая часть является какой.

Было бы также полезно, если бы вы показали фактические выходные данные, полученные при запуске кода.

0 Ответов