udpsock.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:3k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. #include "global.h"
  2. #include "udp.h"
  3. #include "socket.h"
  4. #include "usock.h"
  5. static void s_urcall(struct iface *iface,struct udp_cb *udp,int cnt);
  6. static void autobind(struct usock *up);
  7. int
  8. so_udp(up,protocol)
  9. struct usock *up;
  10. int protocol;
  11. {
  12. return 0;
  13. }
  14. int
  15. so_udp_bind(up)
  16. struct usock *up;
  17. {
  18. int s;
  19. struct sockaddr_in *sp;
  20. struct socket lsock;
  21. s = up->index;
  22. sp = (struct sockaddr_in *)up->name;
  23. lsock.address = sp->sin_addr.s_addr;
  24. lsock.port = sp->sin_port;
  25. up->cb.udp = open_udp(&lsock,s_urcall);
  26. up->cb.udp->user = s;
  27. return 0;
  28. }
  29. int
  30. so_udp_conn(up)
  31. struct usock *up;
  32. {
  33. if(up->name == NULL){
  34. autobind(up);
  35. }
  36. return 0;
  37. }
  38. int
  39. so_udp_recv(up,bpp,from,fromlen)
  40. struct usock *up;
  41. struct mbuf **bpp;
  42. struct sockaddr *from;
  43. int *fromlen;
  44. {
  45. int cnt;
  46. struct udp_cb *udp;
  47. struct sockaddr_in *remote;
  48. struct socket fsocket;
  49. while((udp = up->cb.udp) != NULL
  50. && (cnt = recv_udp(udp,&fsocket,bpp)) == -1){
  51. if(up->noblock){
  52. errno = EWOULDBLOCK;
  53. return -1;
  54. } else if((errno = kwait(up)) != 0){
  55. return -1;
  56. }
  57. }
  58. if(udp == NULL){
  59. /* Connection went away */
  60. errno = ENOTCONN;
  61. return -1;
  62. }
  63. if(from != NULL && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
  64. remote = (struct sockaddr_in *)from;
  65. remote->sin_family = AF_INET;
  66. remote->sin_addr.s_addr = fsocket.address;
  67. remote->sin_port = fsocket.port;
  68. *fromlen = SOCKSIZE;
  69. }
  70. return cnt;
  71. }
  72. int
  73. so_udp_send(
  74. struct usock *up,
  75. struct mbuf **bpp,
  76. struct sockaddr *to
  77. ){
  78. struct sockaddr_in *local,*remote;
  79. struct socket lsock,fsock;
  80. if(up->name == NULL)
  81. autobind(up);
  82. local = (struct sockaddr_in *)up->name;
  83. lsock.address = local->sin_addr.s_addr;
  84. lsock.port = local->sin_port;
  85. if(to != NULL) {
  86. remote = (struct sockaddr_in *)to;
  87. } else if(up->peername != NULL){
  88. remote = (struct sockaddr_in *)up->peername;
  89. } else {
  90. free_p(bpp);
  91. errno = ENOTCONN;
  92. return -1;
  93. }
  94. fsock.address = remote->sin_addr.s_addr;
  95. fsock.port = remote->sin_port;
  96. send_udp(&lsock,&fsock,up->tos,0,bpp,0,0,0);
  97. return 0;
  98. }
  99. int
  100. so_udp_qlen(up,rtx)
  101. struct usock *up;
  102. int rtx;
  103. {
  104. int len;
  105. switch(rtx){
  106. case 0:
  107. len = up->cb.udp->rcvcnt;
  108. break;
  109. case 1:
  110. len = 0;
  111. break;
  112. }
  113. return len;
  114. }
  115. int
  116. so_udp_close(up)
  117. struct usock *up;
  118. {
  119. if(up->cb.udp != NULL){
  120. del_udp(up->cb.udp);
  121. }
  122. return 0;
  123. }
  124. int
  125. so_udp_shut(up,how)
  126. struct usock *up;
  127. int how;
  128. {
  129. int s;
  130. s = up->index;
  131. close_s(s);
  132. return 0;
  133. }
  134. static void
  135. s_urcall(iface,udp,cnt)
  136. struct iface *iface;
  137. struct udp_cb *udp;
  138. int cnt;
  139. {
  140. ksignal(itop(udp->user),1);
  141. kwait(NULL);
  142. }
  143. /* Issue an automatic bind of a local address */
  144. static void
  145. autobind(up)
  146. struct usock *up;
  147. {
  148. struct sockaddr_in local;
  149. int s;
  150. s = up->index;
  151. local.sin_family = AF_INET;
  152. local.sin_addr.s_addr = INADDR_ANY;
  153. local.sin_port = Lport++;
  154. bind(s,(struct sockaddr *)&local,sizeof(struct sockaddr_in));
  155. }
  156. int
  157. so_udp_stat(up)
  158. struct usock *up;
  159. {
  160. st_udp(up->cb.udp,0);
  161. return 0;
  162. }