我正致力于实现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, '\0', "octet", '\0');
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;
}
}
答案 0 :(得分:4)
TFTP协议具有以下流程:
客户端从随机选择的CTID端口向服务器上的端口69发送RRQ
或WRQ
请求:
客户:CTID ------>服务器:69
服务器从随机选择的STID端口回复到客户端的CTID:
客户:CTID< ------服务器:STID
该传输的所有后续数据包将根据需要在客户端的CTID和服务器的STID之间发送。
客户:CTID< ----->服务器:STID
每台计算机都会选择自己的源 TID端口,以便将数据包发送到另一方的目的地 TID端口。
如上所示,CTID和STID由相应的机器选择,最好随机选择。在您的代码中,您没有为请求设置源端口,因此操作系统会随机选择它。哪个适用于您的传出数据包,但防火墙不知道入站数据包的来源。因此,您需要将bind()
套接字连接到特定端口,然后可以在防火墙中打开该端口。否则,请检查防火墙设置,看看它是否有可用的规则,允许来自最近发送的传出UDP数据包的IP地址的入站UDP数据包,或类似的规则。