固定端口的socket通信
2015-11-14 00:02
330 查看
在多台机器互联的场景下,可能会出现无法通信的情形,可能原因有:代码出错,地址出错,防火墙。对于防火墙的命令,后面会提及。
对于前两种错误debug就可以解决。如果这两种情况都不是,那么极有可能是防火墙的问题,我们可以通过wireshark来抓包进行分析。在wireshark抓包中,我们看到当fedora作为服务器接受到客户端的请求之后,给主机发回的信息会被host administratively prohibited。由此判断出是防火墙的问题。
对于防火墙拒绝了数据包,我们可以用两种方式处理:
1. 直接关闭防火墙,不推荐,但我们使用的是这个。
2. 通过在防火墙上添加允许通过的端口号来打开我们需要的端口。
所以,绑定端口的UDP通信十分必要。首先,我们需要知道的是
客户端所初始化的struct sockaddr_in 的端口、地址都是所发送到的服务器端的端口、地址。而服务器端所初始化的struct sockaddr_in 是指其本身监听的端口和地址。其次,如果想要固定端口号,对sendto()函数的参数有所要求,第一个参数为我们绑定了客户端地址、端口号的套接字,第五个参数则为赋值了服务器的端口号、地址的sockaddr_in。这里的一个小技巧是声明一个strcut sockaddr_in 变量,在对其初始化客户端端口号、地址并绑定过套接字后,再对此变量重新赋值为服务器的客户端、地址。服务器端会根据收到的数据包中的客户端端口号、地址回复。
下面给出固定端口号的客户端代码,因为服务端会根据客户端的端口号来回复。
这里我们只给出main函数,因为另外两个函数依然可用上一篇
linux下socket通信代码的开发及总结—UDP的内容
/article/11259808.html
值得一提的是,代码中用了多线程来实现,也可以不用线程,直接用循环来实现。代码中只需把注释掉的部分取消注释,并且去掉线程的部分即可。
对于前两种错误debug就可以解决。如果这两种情况都不是,那么极有可能是防火墙的问题,我们可以通过wireshark来抓包进行分析。在wireshark抓包中,我们看到当fedora作为服务器接受到客户端的请求之后,给主机发回的信息会被host administratively prohibited。由此判断出是防火墙的问题。
对于防火墙拒绝了数据包,我们可以用两种方式处理:
1. 直接关闭防火墙,不推荐,但我们使用的是这个。
2. 通过在防火墙上添加允许通过的端口号来打开我们需要的端口。
所以,绑定端口的UDP通信十分必要。首先,我们需要知道的是
客户端所初始化的struct sockaddr_in 的端口、地址都是所发送到的服务器端的端口、地址。而服务器端所初始化的struct sockaddr_in 是指其本身监听的端口和地址。其次,如果想要固定端口号,对sendto()函数的参数有所要求,第一个参数为我们绑定了客户端地址、端口号的套接字,第五个参数则为赋值了服务器的端口号、地址的sockaddr_in。这里的一个小技巧是声明一个strcut sockaddr_in 变量,在对其初始化客户端端口号、地址并绑定过套接字后,再对此变量重新赋值为服务器的客户端、地址。服务器端会根据收到的数据包中的客户端端口号、地址回复。
下面给出固定端口号的客户端代码,因为服务端会根据客户端的端口号来回复。
这里我们只给出main函数,因为另外两个函数依然可用上一篇
linux下socket通信代码的开发及总结—UDP的内容
/article/11259808.html
int main(int argc, char** argv){ /* check args */ if (argc !=2){ printf("Usage: udp_request IP\n"); exit(1); } //创建两个线程 pthread_t threadrecv,threadsend; void *retval; int port = 4600; int udp_descriptor; struct sockaddr_in udpaddr; //固定客户端端口号为4600 bzero(&udpaddr,sizeof(udpaddr)); udpaddr.sin_family=AF_INET; udpaddr.sin_port=htons(port); udpaddr.sin_addr.s_addr= inet_addr("192.168.1.3");//这里的地址应该为你客户端所用的ip地址 int udp_descriptor = socket(AF_INET,SOCK_DGRAM,0); if(udp_descriptor == -1){ printf("Create Socket Failed!\n"); exit(1); } if(bind(udp_descriptor,(struct sockaddr*)&udpaddr,sizeof(udpaddr)) == -1 ){ printf("Server Bind Failed!\n"); exit(1); } udpaddr.sin_port=htons(port); inet_pton(AF_INET, argv[1], &udpaddr.sin_addr); struct argu_send args; args.adres =&udpaddr; args.sock = udp_descriptor; /*while(1) { send_msg(&args); get_msg(server_descriptor); sleep(3); }*/ pthread_create(&threadsend,NULL,(void*)(&send_msg),&args); pthread_create(&threadrecv,NULL,(void*)(&get_msg),&udp_descriptor); pthread_join(threadrecv,&retval); pthread_join(threadsend,&retval); return 0; }
值得一提的是,代码中用了多线程来实现,也可以不用线程,直接用循环来实现。代码中只需把注释掉的部分取消注释,并且去掉线程的部分即可。
相关文章推荐
- Day Seven
- best-time-to-buy-and-sell-stock I &&II && III && IVbest-time-to-buy-and-sell-stock-ii
- linux下单用户更改root密码
- Mesos Framework Failover
- 使用jsp:include控制动态内容的方法
- PHP使用Pthread实现的多线程操作实例
- php实现的递归提成方案实例
- android中的Dialog的使用
- PHP实现操作redis的封装类完整实例
- PHP+redis实现添加处理投票的方法
- PHP使用redis实现统计缓存mysql压力的方法
- PHP实现的一致性哈希算法完整实例
- PHP使用PHPexcel导入导出数据的方法
- PHP常用的小程序代码段
- php经典算法集锦
- python实现mysql的单引号字符串过滤方法
- javascript动态生成树形菜单的方法
- 基于JS实现PHP的sprintf函数实例
- js读取并解析JSON类型数据的方法
- JS使用eval解析JSON的注意事项分析