swudp.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /************************************************************************
  2. * AUTHOR: NiuJiuRu
  3. * FILENAME: swudp.c
  4. * DESCRIPTION: UDP socket
  5. * NOTE:
  6. * HISTORY:
  7. * 1, [2010-11-30] created by NiuJiuRu
  8. ***********************************************************************/
  9. #include "swapi.h"
  10. #include "swudp.h"
  11. /* 创建一个udp socket */
  12. int sw_udp_socket()
  13. {
  14. return socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
  15. }
  16. /* 关闭一个udp socket */
  17. void sw_udp_close(int skt)
  18. {
  19. closesocket(skt);
  20. }
  21. /* 绑定接收地址和端口 */
  22. int sw_udp_bind(int skt, unsigned int ip, unsigned short port)
  23. {
  24. struct sockaddr_in addr;
  25. addr.sin_family = AF_INET;
  26. addr.sin_addr.s_addr = ip;
  27. addr.sin_port = port;
  28. return bind(skt, (struct sockaddr *)&addr, sizeof(addr));
  29. }
  30. /* 加入一个多播组 */
  31. int sw_udp_join(int skt, unsigned int ip)
  32. {
  33. int ttl = 127;
  34. bool fFlag = true;
  35. struct ip_mreq mreq;
  36. if(IS_MULTICAST_IP(ip))
  37. {
  38. mreq.imr_multiaddr.s_addr = ip;
  39. mreq.imr_interface.s_addr = INADDR_ANY;
  40. if(setsockopt(skt, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) == SOCKET_ERROR)
  41. {
  42. sw_log_error("add to one multicast group error!!");
  43. return -1;
  44. }
  45. if(setsockopt(skt, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) == SOCKET_ERROR)
  46. {
  47. sw_log_warn("set multicast ttl args fail!");
  48. }
  49. if(setsockopt(skt, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&fFlag, sizeof(fFlag)) == SOCKET_ERROR)
  50. {
  51. sw_log_warn("set multicast loopback args fail!");
  52. }
  53. }
  54. return 0;
  55. }
  56. /* 退出一个多播组 */
  57. int sw_udp_drop(int skt, unsigned int ip)
  58. {
  59. struct ip_mreq mreq;
  60. if(IS_MULTICAST_IP(ip))
  61. {
  62. mreq.imr_multiaddr.s_addr = ip;
  63. mreq.imr_interface.s_addr = INADDR_ANY;
  64. return setsockopt(skt, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
  65. }
  66. return 0;
  67. }
  68. /* 发送数据 */
  69. int sw_udp_send(int skt, unsigned int ip, unsigned short port, char *buf, int send_len)
  70. {
  71. struct sockaddr_in to;
  72. unsigned int len = sizeof(to);
  73. to.sin_family = AF_INET;
  74. to.sin_addr.s_addr = ip;
  75. to.sin_port= port;
  76. return sendto(skt, buf, send_len, 0, (struct sockaddr *)&to, len);
  77. }
  78. /* 接收数据 */
  79. int sw_udp_recv(int skt, unsigned int *ip, unsigned short *port, char *buf, int buf_size)
  80. {
  81. struct sockaddr_in from;
  82. unsigned int len = sizeof(from);
  83. len = recvfrom(skt, buf, buf_size, 0, (struct sockaddr *)&from, &len);
  84. if(ip) *ip = from.sin_addr.s_addr;
  85. if(port) *port = from.sin_port;
  86. return len;
  87. }
  88. /* 配置udp socket */
  89. int sw_udp_ioctl(int skt, int type, unsigned long *val)
  90. {
  91. return ioctlsocket(skt, (long)type, val);
  92. }
  93. /* 检测udp socket的状态, timeout单位为ms */
  94. int sw_udp_select(int skt, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout)
  95. {
  96. struct timeval tv = { 0 };
  97. if(readfds)
  98. {
  99. FD_ZERO(readfds);
  100. FD_SET((unsigned int)skt, readfds);
  101. }
  102. if(writefds)
  103. {
  104. FD_ZERO(writefds);
  105. FD_SET((unsigned int)skt, writefds);
  106. }
  107. if(exceptfds)
  108. {
  109. FD_ZERO(exceptfds);
  110. FD_SET((unsigned int)skt, exceptfds);
  111. }
  112. if(0 <= timeout)
  113. {
  114. tv.tv_sec = timeout/1000;
  115. tv.tv_usec = (timeout%1000)*1000;
  116. return select(skt+1, readfds, writefds, exceptfds, &tv);
  117. }
  118. else
  119. return select(skt+1, readfds, writefds, exceptfds, NULL);
  120. }