linux——TCP服务器获取客户端IP地址
之前的服务器端代码不灵活今天对他进行优化1、优化1使用INADDR_ANY绑定IP旧代码sin.sin_addr.s_addr inet_addr(192.168.88.129);优化后sin.sin_addr.s_addr INADDR_ANY;这个优化的意思旧写法服务器只绑定固定 IP换一台电脑、换一个网卡、换一个网段 →连接失败新写法 INADDR_ANY服务器绑定本机所有网卡 IP不管服务器 IP 是多少不管是哪个网卡不管是内网、外网、虚拟机客户端都能连接优点总结不挑 IP不挑网卡代码可移植性极强正式项目服务器 100% 这么写2、优化2accept 时获取客户端 IP 端口正式服务器必备旧代码newfd accept(fd, NULL, NULL);只拿连接不关心客户是谁优化后// 新版 struct sockaddr_in cin; socklen_t addrlen sizeof(cin); newfd accept(fd,(struct sockaddr *)cin,addrlen); char ipv4_addr[16]; inet_ntop(AF_INET, cin.sin_addr, ipv4_addr, sizeof(ipv4_addr)); printf(Client:(%s,%d) is connect\n, ipv4_addr, ntohs(cin.sin_port));①struct sockaddr_in cin;cin client in 的意思作用准备一个空盒子用来装客户端的 IP、端口这个结构体和服务端的sin一模一样只是名字不同②socklen_t addrlen sizeof(cin);addrlen地址结构体的长度为什么要写accept 函数要求必须传一个 “地址长度的指针”这是固定写法背下来③newfd accept(fd, (struct sockaddr *)cin, addrlen);旧版后面的两个参数是NULL优化后会自动的把客户端的IP、端口存到cin里④char ipv4_addr[16];用来存字符串格式的IP⑤inet_ntop(AF_INET, cin.sin_addr, ipv4_addr, sizeof(ipv4_addr));把cin里的二进制IP转成字符串IP⑥printf(Client:(%s,%d) is connect\n, ipv4_addr, ntohs(cin.sin_port));打印两个东西ipv4_addr→ 客户端 IPntohs(cin.sin_port)→ 客户端端口为什么用 ntohs因为端口在网络里是网络字节序要转成主机字节序才能正常打印。ntohs network to host short这个优化的意思旧版只知道有人连接了但不知道是谁连的。新版accept 时自动把客户端的 IP 地址、客户端端口号取出来然后打印这个优化的 3 个好处可以知道谁连接了服务器方便日志记录正式网络程序必须这么写#includestdio.h #include sys/types.h /* See NOTES */ #include sys/socket.h #include unistd.h #includestdlib.h #include strings.h #include arpa/inet.h #includestring.h #define QUIT_STR QUIT #define BUFSIZE 1024 #define BACKLOG 5 #define SERV_IP 5001 #define SERV_IP_ADDR 192.168.88.129 int main() { int fd -1; struct sockaddr_in sin; //1.socket fd socket(AF_INET,SOCK_STREAM,0); if(fd0) { perror(socket); exit(1); } bzero(sin,sizeof(sin)); sin.sin_family AF_INET; sin.sin_port htons(SERV_IP); //sin.sin_addr.s_addr inet_addr(SERV_IP_ADDR); sin.sin_addr.s_addr INADDR_ANY; /*if(inet_pion(AF_INET,SERV_IP_ADDR,(void *)sin.sin_addr.s_addr) ! 1) { perror(inet_pton); exit(1); } */ //2.bind if(bind(fd,(struct sockaddr *)sin,sizeof(sin)) 0) { perror(bind); exit(0); } //3.listen if(listen(fd,BACKLOG) 0) { perror(listen); exit(1); } //4.accept /*int newfd -1; newfd accept(fd,NULL,NULL); if(newfd 0) { perror(accept); exit(1); } */ int newfd -1; struct sockaddr_in cin; socklen_t addrlen sizeof(cin); newfd accept(fd,(struct sockaddr *)cin,addrlen); if(newfd 0) { perror(accept); exit(1); } char ipv4_addr[16]; if(!inet_ntop(AF_INET,(void *)cin.sin_addr,ipv4_addr,sizeof(cin))) { perror(inet_ntop); exit(1); } printf(Client:(%s,%d) is connect\n,ipv4_addr,ntohs(cin.sin_port)); char buf[BUFSIZE]; int ret -1; //read while(1) { do { bzero(buf,BUFSIZE); ret read(newfd,buf,BUFSIZE-1); }while(ret 1); if(ret 0) { exit(1); } if(!ret) { break; } printf(receive data:%s\n,buf); if(!strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) { printf(Client is exiting!\n); break; } } close(newfd); close(fd); return 0; }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2510070.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!