Я пишу свой собственный TFTP-клиент. Клиент написан на c++ (частично на c) и работает в системе unix (стабильная версия Linux Debian).
Вот моя проблема:
Я могу отправить свой запрос на чтение (RRQ) на TFTP-сервер (открытый TFTP-сервер в Windows XP). TFTP-сервер получает RRQ, но не может отправить ответ.
На стороне сервера я вижу это сообщение: Client 192.168.1.110:55239 C:\OpenTFTPServer\test.txt, Ошибка связи
Но порт 55239 — это не тот порт, который я определил в своем TFTP-клиенте.
Вот мои части кода:
установить адреса клиента и сервера:
memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(servport); // servport=69 servaddr.sin_addr.s_addr = inet_addr("192.168.1.152"); memset(&cliaddr,0,sizeof(cliaddr)); cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(cliport); // cliport=13337 cliaddr.sin_addr.s_addr = inet_addr("192.168.1.110");
подключить и привязать:
if (connect(serv, (struct sockaddr *) &servaddr, serv_length) < 0) { bail("Unable to connect with the server!"); } if(bind(cli, (struct sockaddr *)&cliaddr, cli_length)<0) { bail("Unable to bind to adr & port!"); }
создать запрос TFTP:
memset( &cBuf1, 0, sizeof cBuf1); rdwrFrame = (struct tftp_wr_rq *)&cBuf1; rdwrFrame->opcode=htons(1); rdwrFrame->data={'t','e','s','t','.','t','x','t','\0','o','c','t','e','t','\0'};
отправить TFTP-запрос:
if (sendto (serv,cBuf1,19,0,(struct sockaddr *)&servaddr,serv_length) < 0) { bail ("Send the first requirment Frame error -- UDP"); }
Вот мой вопрос:
Что я делаю не так, что TFTP-сервер получает не тот порт? Я думал, что это должно быть установлено с помощью cliaddr.sin_port = htons(cliport);
Спасибо за помощь и с уважением Рико
Ответ:
Моя проблема заключалась в том, что я объединил неправильные сокеты с неправильными адресными структурами.
Вот мои рабочие части кода:
создать сокеты:
serv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (serv < 0) { bail("Unable to create socket tx!"); } cli = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (cli < 0) { bail("Unable to create socket rx!"); }
установить адреса клиента и сервера:
memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(servport); servaddr.sin_addr.s_addr = inet_addr("192.168.1.152"); memset(&cliaddr,0,sizeof(cliaddr)); cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(cliport); cliaddr.sin_addr.s_addr = inet_addr("192.168.1.110");
подключить и привязать:
if(bind(cli, (struct sockaddr *)&cliaddr, cli_length)<0) { bail("Unable to bind to adr & port!"); } if (connect(serv, (struct sockaddr *) &servaddr, serv_length) < 0) { bail("Unable to connect with the server!"); }
создать TFTP-запрос:
memset( &cBuf1, 0, sizeof cBuf1); rdwrFrame = (struct tftp_wr_rq *)&cBuf1; rdwrFrame->opcode=htons(1); rdwrFrame->data={'t','e','s','t','.','t','x','t',(char)0,'o','c','t','e','t',(char)0};
отправить TFTP-запрос:
if (sendto (cli,cBuf1,19,0,(struct sockaddr *)&servaddr,serv_length) < 0) { bail ("Send the first requirment Frame error -- UDP"); }
получить данные:
recvfrom(cli,cBuf2,19,0,(struct sockaddr *)&cliaddr,(socklen_t*)&cli_length);
cliaddr.sin_port = 13337
? - person GMasucci   schedule 21.12.2012cliaddr.sin_port=13337;
и это:cliaddr.sin_port=htons(13337);
, но я все еще вижу случайный порт при просмотре сервера - person i3luefire   schedule 21.12.2012sendto (serv,cBuf1,19,0,(struct sockaddr*)&servaddr,serv_length)
, но для получения он должен быть в форматеconnect(intValHere,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
. Я думаю, что проблема может заключаться в формате подключения. Думаю, вы просто пропустили sizeof в соединении. В любом случае, поздно я знаю, и я могу расширить или дать более подробный ответ. - person GMasucci   schedule 21.12.2012sizeof(serv_addr)
- Хорошо, я понял, как отправить пакет с правильным исходным портом. Я делаю ошибку, создавая 2 сокета, сокет rx и tx (cli и serv), затем я привязываюсь к сокету cli и подключаюсь к сокету serv. Таким образом, сообщение было отправлено без определенного порта и получило случайное число. Теперь проблема в том, что я все еще не получаю ответа в своем клиенте и все еще получаю сообщение об ошибке связи из-за недоступного порта. - person i3luefire   schedule 21.12.2012clientRcvPort = mychoice clientSendPort = servRcvPort
на сервереservRcvPort = clientSendPort servSendPort = clientRcvPort
не настоящий код, просто для иллюстрации, если эти порты не совпадают в этом порядке, тогда вы можете получить что-то сломанное - person GMasucci   schedule 21.12.2012