#ifndef _UDP_H #define _UDP_H #include #include #include #include #include #include #include #include #include #include "debug.h" #include "mychat.h" /********************UDP广播 点对点通信*************************/ /* 信息检测 */ extern char udp_info_check(struct sockaddr_in *sin) { if (!sin) { pr_debug("地址为空\n"); return -1; } char ip[16]; u_short port; inet_ntop(AF_INET, (void *)&(sin->sin_addr.s_addr), ip, sizeof(ip)); port = ntohs(sin->sin_port); pr_debug("信息检测地址:%s:%d\n", ip, port); return 1; } /* 接收到(绑定IP, 绑定端口, 客户信息, 内容) */ extern char udp_recv_from(char *ip, int port, struct sockaddr_in *recv_cin, struct msg_udp *recv_msg) { int ret = -1; struct sockaddr_in sin; int udp_recv_fd; udp_recv_fd = socket(AF_INET, SOCK_DGRAM, 0); if(udp_recv_fd < 0) { perror("udp_recv_from->socket\nError:"); return udp_recv_fd; } sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = inet_addr(ip); bzero(sin.sin_zero, 8); do{ ret = bind(udp_recv_fd, (struct sockaddr*)&sin, sizeof(sin)); if (ret < 0) { perror("udp_recv_from->bind\nError:"); udp_info_check(&sin); sleep(1); } } while (ret < 0); struct msg_udp msg_buf; struct sockaddr cin_in; socklen_t addrlen= sizeof(struct sockaddr); bzero(&msg_buf, sizeof(msg_buf)); bzero(&cin_in, addrlen); ret = recvfrom(udp_recv_fd, &msg_buf, sizeof(msg_buf), 0, &cin_in, &addrlen); if (ret < 0) { perror("udp_recv_from->recvfrom\nError:"); return ret; } memcpy(recv_msg, &msg_buf, sizeof(msg_buf)); memcpy(recv_cin, &cin_in, sizeof(struct sockaddr_in)); close(udp_recv_fd); return 1; } /* 发送(IP,端口,信息) */ extern char udp_send_to(char *ip, unsigned int port, struct msg_udp *str, int size_str) { int ret = -1; struct sockaddr_in sin; int udp_send_fd; udp_send_fd = socket(AF_INET, SOCK_DGRAM, 0); if(udp_send_fd < 0) { perror("udp_send_to->socket\nError:"); return udp_send_fd; } sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = inet_addr(ip); bzero(sin.sin_zero, 8); ret = sendto(udp_send_fd, str, size_str, 0, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)); if (ret < 0) { perror("udp_send_to->sendto\nError:"); udp_info_check(&sin); return ret; } close(udp_send_fd); return 1; } /* 发送(地址,信息, 大小) */ extern char udp_addr_send_to(struct sockaddr_in *sin, struct msg_udp *str, int size_str) { int ret = -1; int udp_send_fd; udp_send_fd = socket(AF_INET, SOCK_DGRAM, 0); if(udp_send_fd < 0) { perror("udp_addr_send_to->socket\nError:"); return udp_send_fd; } ret = sendto(udp_send_fd, str, size_str, 0, (struct sockaddr*)sin, sizeof(*sin)); if (ret < 0) { perror("udp_addr_send_to->sendto\nError:"); udp_info_check(sin); return ret; } close(udp_send_fd); return 1; } /********************UDP广播 接受与发送*************************/ /* 接收到(绑定IP, 绑定端口, 客户信息, 内容) */ extern char udp_broad_recv_from(uint32_t ip, int port, struct sockaddr_in *online_cin, struct msg_udp *recv_msg) { int ret = -1; struct sockaddr_in sin; int udp_broad_recv_fd; udp_broad_recv_fd = socket(AF_INET, SOCK_DGRAM, 0); if(udp_broad_recv_fd < 0) { perror("udp_broad_recv_from->socket\nError:"); return udp_broad_recv_fd; } const int opt = 1; //设置该套接字为广播类型, ret = setsockopt(udp_broad_recv_fd, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)); if(ret < 0) { perror("udp_broad_recv_from->setsockopt\nError:"); return ret; } sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = htonl(ip);//inet_addr(ip); bzero(sin.sin_zero, 8); do{ ret = bind(udp_broad_recv_fd, (struct sockaddr*)&sin, sizeof(sin)); if (ret < 0) { perror("udp_broad_recv_from->bind\nError:"); udp_info_check(&sin); sleep(1); } } while (ret < 0); struct msg_udp msg_buf; struct sockaddr cin_in; socklen_t addrlen= sizeof(cin_in); bzero(&msg_buf, sizeof(msg_buf)); bzero(&cin_in, addrlen); ret = recvfrom(udp_broad_recv_fd, &msg_buf, sizeof(msg_buf), 0, &cin_in, &addrlen); if (ret < 0) { perror("udp_broad_recv_from->recvfrom\nError:"); return ret; } memcpy(recv_msg, &msg_buf, sizeof(msg_buf)); memcpy(online_cin, &cin_in, addrlen); close(udp_broad_recv_fd); return 1; } /* 发送(IP,端口,信息) */ extern char udp_broad_send_to(uint32_t ip, unsigned int port, struct msg_udp *str, int size_str) { int ret = -1; struct sockaddr_in sin; int udp_broad_send_fd; udp_broad_send_fd = socket(AF_INET, SOCK_DGRAM, 0); const int opt = 1; //设置该套接字为广播类型, ret = setsockopt(udp_broad_send_fd, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)); if(ret < 0) { perror("udp_broad_send_to->setsockopt\nError:"); return ret; } sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = htonl(ip); //inet_addr(ip); bzero(sin.sin_zero, 8); ret = sendto(udp_broad_send_fd, str, size_str, 0, (struct sockaddr*)&sin, sizeof(sin)); if (ret < 0) { perror("udp_broad_send_to->sendto\nError:"); udp_info_check(&sin); return ret; } close(udp_broad_send_fd); return 1; } #endif