正在检测 TFTP 数据的传入端口?
Detecting incoming port for TFTP data?
我正在努力实现 TFTP 客户端(UDP 套接字)。
目前我必须关闭 Windows 8 机器上的整个防火墙,否则数据无法到达 TFTP 客户端。传出连接请求发生在端口 69 上,但来自 TFTP 服务器的第一个数据包在不同的随机端口上传回。所以我的问题是:如何确保 TFTP 客户端(作为应用程序)能够在打开防火墙的机器上接收数据包?
当我在 Visual Studio 2005 年 运行 处于调试模式的 TFTP 客户端时,客户端也收不到数据包,除非我关闭防火墙。我该如何解决?
谢谢
更新(代码)
void main(void)
{
unsigned short OPCODE = htons((unsigned short)1);
char* fileName = "thisfile.cnf.xml";
WORD wVersionRequested;
WSADATA wsaData;
int err;
SOCKET sockfd;
int n;
char buf[256] = {0};
int L;
struct sockaddr_in servaddr;
char recvline[1000];
int rc;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
memcpy(buf, &OPCODE, 2);
sprintf_s(&buf[2], 254, "%s%c%s%c", fileName, '[=10=]', "octet", '[=10=]');
L = (int) strlen(fileName) + 9;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr("212.158.10.33");
servaddr.sin_port=htons(69);
rc = sendto(sockfd,buf,L,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
while (1)
{
printf("Receive 1st packet...\n");
/* This call gets blocked unless firewall is off */
n=recvfrom(sockfd,recvline,1000,0,NULL,NULL);
printf("%d bytes received\n", n);
break;
}
}
TFTP协议流程如下:
客户端从随机选择的CTID端口向服务器的69端口发送RRQ
或WRQ
请求:
客户端:CTID ------> Server:69
服务器从随机选择的 STID 端口回复客户端的 CTID:
客户端:CTID <------ Server:STID
该传输的所有后续数据包都根据需要在客户端的 CTID 和服务器的 STID 之间发送。
客户端:CTID <-----> Server:STID
每台机器都选择自己的 source TID 端口用于将发送到另一方的 destination TID 端口的数据包。
正如你在上面看到的,CTID和STID是由相应的机器选择的,最好是随机选择的。在您的代码中,您没有为您的请求设置 源端口 ,因此它是由 OS 随机选择的。这对您的传出数据包没问题,但防火墙不知道入站数据包的来源。所以你需要 bind()
你的套接字到一个特定的端口,然后你可以在你的防火墙中打开它。否则,请检查您的防火墙设置,看看它是否有可用的规则,允许来自最近发送 UDP 数据包的 IP 地址的入站 UDP 数据包,或类似的规则。
我正在努力实现 TFTP 客户端(UDP 套接字)。
目前我必须关闭 Windows 8 机器上的整个防火墙,否则数据无法到达 TFTP 客户端。传出连接请求发生在端口 69 上,但来自 TFTP 服务器的第一个数据包在不同的随机端口上传回。所以我的问题是:如何确保 TFTP 客户端(作为应用程序)能够在打开防火墙的机器上接收数据包?
当我在 Visual Studio 2005 年 运行 处于调试模式的 TFTP 客户端时,客户端也收不到数据包,除非我关闭防火墙。我该如何解决?
谢谢
更新(代码)
void main(void)
{
unsigned short OPCODE = htons((unsigned short)1);
char* fileName = "thisfile.cnf.xml";
WORD wVersionRequested;
WSADATA wsaData;
int err;
SOCKET sockfd;
int n;
char buf[256] = {0};
int L;
struct sockaddr_in servaddr;
char recvline[1000];
int rc;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
memcpy(buf, &OPCODE, 2);
sprintf_s(&buf[2], 254, "%s%c%s%c", fileName, '[=10=]', "octet", '[=10=]');
L = (int) strlen(fileName) + 9;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr("212.158.10.33");
servaddr.sin_port=htons(69);
rc = sendto(sockfd,buf,L,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
while (1)
{
printf("Receive 1st packet...\n");
/* This call gets blocked unless firewall is off */
n=recvfrom(sockfd,recvline,1000,0,NULL,NULL);
printf("%d bytes received\n", n);
break;
}
}
TFTP协议流程如下:
客户端从随机选择的CTID端口向服务器的69端口发送
RRQ
或WRQ
请求:客户端:CTID ------> Server:69
服务器从随机选择的 STID 端口回复客户端的 CTID:
客户端:CTID <------ Server:STID
该传输的所有后续数据包都根据需要在客户端的 CTID 和服务器的 STID 之间发送。
客户端:CTID <-----> Server:STID
每台机器都选择自己的 source TID 端口用于将发送到另一方的 destination TID 端口的数据包。
正如你在上面看到的,CTID和STID是由相应的机器选择的,最好是随机选择的。在您的代码中,您没有为您的请求设置 源端口 ,因此它是由 OS 随机选择的。这对您的传出数据包没问题,但防火墙不知道入站数据包的来源。所以你需要 bind()
你的套接字到一个特定的端口,然后你可以在你的防火墙中打开它。否则,请检查您的防火墙设置,看看它是否有可用的规则,允许来自最近发送 UDP 数据包的 IP 地址的入站 UDP 数据包,或类似的规则。