/************************************************************************ * AUTHOR: NiuJiuRu * FILENAME: swudp.c * DESCRIPTION: UDP socket * NOTE: * HISTORY: * 1, [2010-11-30] created by NiuJiuRu ***********************************************************************/ #include "swapi.h" #include "swudp.h" /* 创建一个udp socket */ int sw_udp_socket() { return socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); } /* 关闭一个udp socket */ void sw_udp_close(int skt) { closesocket(skt); } /* 绑定接收地址和端口 */ int sw_udp_bind(int skt, unsigned int ip, unsigned short port) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = ip; addr.sin_port = port; return bind(skt, (struct sockaddr *)&addr, sizeof(addr)); } /* 加入一个多播组 */ int sw_udp_join(int skt, unsigned int ip) { int ttl = 127; bool fFlag = true; struct ip_mreq mreq; if(IS_MULTICAST_IP(ip)) { mreq.imr_multiaddr.s_addr = ip; mreq.imr_interface.s_addr = INADDR_ANY; if(setsockopt(skt, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) == SOCKET_ERROR) { sw_log_error("add to one multicast group error!!"); return -1; } if(setsockopt(skt, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) == SOCKET_ERROR) { sw_log_warn("set multicast ttl args fail!"); } if(setsockopt(skt, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&fFlag, sizeof(fFlag)) == SOCKET_ERROR) { sw_log_warn("set multicast loopback args fail!"); } } return 0; } /* 退出一个多播组 */ int sw_udp_drop(int skt, unsigned int ip) { struct ip_mreq mreq; if(IS_MULTICAST_IP(ip)) { mreq.imr_multiaddr.s_addr = ip; mreq.imr_interface.s_addr = INADDR_ANY; return setsockopt(skt, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); } return 0; } /* 发送数据 */ int sw_udp_send(int skt, unsigned int ip, unsigned short port, char *buf, int send_len) { struct sockaddr_in to; unsigned int len = sizeof(to); to.sin_family = AF_INET; to.sin_addr.s_addr = ip; to.sin_port= port; return sendto(skt, buf, send_len, 0, (struct sockaddr *)&to, len); } /* 接收数据 */ int sw_udp_recv(int skt, unsigned int *ip, unsigned short *port, char *buf, int buf_size) { struct sockaddr_in from; unsigned int len = sizeof(from); len = recvfrom(skt, buf, buf_size, 0, (struct sockaddr *)&from, &len); if(ip) *ip = from.sin_addr.s_addr; if(port) *port = from.sin_port; return len; } /* 配置udp socket */ int sw_udp_ioctl(int skt, int type, unsigned long *val) { return ioctlsocket(skt, (long)type, val); } /* 检测udp socket的状态, timeout单位为ms */ int sw_udp_select(int skt, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout) { struct timeval tv = { 0 }; if(readfds) { FD_ZERO(readfds); FD_SET((unsigned int)skt, readfds); } if(writefds) { FD_ZERO(writefds); FD_SET((unsigned int)skt, writefds); } if(exceptfds) { FD_ZERO(exceptfds); FD_SET((unsigned int)skt, exceptfds); } if(0 <= timeout) { tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000; return select(skt+1, readfds, writefds, exceptfds, &tv); } else return select(skt+1, readfds, writefds, exceptfds, NULL); }