Мой вопрос заключается в следующем: во время TFTP, когда клиент подключается к серверу, порт по умолчанию для первоначальной передачи данных является порт 69. Когда сервер получает пакет WRQ (запрос на запись) от клиента, он возвращает пакет ACK (подтверждение) , Однако этот пакет ACK отправляется через другой порт обратно клиенту. ниже приведена функция, которую я использую для подключения к серверу. Обратите внимание, что server_port — 69.
int TFTPClient::connectToServer() {
socket_descriptor = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (socket_descriptor == -1) {
throw new ETFTPSocketCreate;
}
client_address.sin_family = AF_INET;
client_address.sin_port = htons(server_port);
client_address.sin_addr.s_addr = inet_addr(this->server_ip);
connection = connect(socket_descriptor, (const struct sockaddr *)&client_address, sizeof(client_address));
if (connection != 0) {
cout << "Unable to connect to an address\n";
return -1;
}
DEBUGMSG("Successfully connected");
AfxMessageBox("Successfully connected");
return 1;
}int TFTPClient::sendPacket(TFTP_Packet* packet) {
return send(socket_descriptor, (char*)packet->getData(), packet->getSize(), 0);
}
int TFTPClient::waitForPacket(TFTP_Packet* packet, int timeout_ms) {
packet->clear();
int receive_status;
int iResult;
u_long iMode = 0;
//-----------------------------------------------
// Set the socket I/O mode: In this case FIONBIO
// enables or disables the blocking mode for the
// socket based on the numerical value of iMode.
// If iMode = 0, blocking is enabled;
// If iMode != 0, non-blocking mode is enabled.
//-----------------------------------------------
iResult = ioctlsocket(socket_descriptor, FIONBIO, &iMode);
if (iResult != NO_ERROR){
printf("ioctlsocket failed with error: %ld\n", iResult);
}
receive_status = recv(socket_descriptor, (char*)packet->getData(), TFTP_PACKET_MAX_SIZE, 0);
if (receive_status == 0) {
cout << "Connection was closed by server\n";
return TFTP_CLIENT_ERROR_CONNECTION_CLOSED;
}
if (receive_status == SOCKET_ERROR) {
DEBUGMSG("recv() error in waitForPackage()");
return TFTP_CLIENT_ERROR_RECEIVE;
}
packet->setSize(receive_status);
return TFTP_CLIENT_ERROR_NO_ERROR;
}
Я использую Wire Shark для определения передачи данных через сокет. Я отправляю пакет WRQ, который успешно достигает сервера. Пакет ACK (в соответствии с Wireshark) успешно отправляется обратно клиенту (через другой порт). Тем не менее, мое приложение зависает на неопределенное время, когда я нажимаю функцию ‘recv ()’. Я боюсь, что это может быть связано с тем, что я вызываю тот же сокет (‘socket_descriptor’) в функции recv (), которую я вызвал в функции send (). Является ли спецификация порта 69 ‘socket_descriptor’ причиной остановки этого приложения? Или recv () принимает пакеты от сервера IP через другие порты ?? Может кто-нибудь пролить свет на это, пожалуйста?
Задача ещё не решена.