IOCTL.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:7k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. * ioctl.c - TCP server
  3. *
  4. *       This is a part of the Microsoft Source Code Samples.
  5. *       Copyright 1996-1997 Microsoft Corporation.
  6. *       All rights reserved.
  7. *       This source code is only intended as a supplement to
  8. *       Microsoft Development Tools and/or WinHelp documentation.
  9. *       See these sources for detailed information regarding the
  10. *       Microsoft samples programs.
  11. ******************************************************************************/
  12. #define WIN32_LEAN_AND_MEAN
  13. #include <winsock2.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #define DEFAULT_PORT 5001
  18. int ReadAndEcho(SOCKET , char *,int ) ;
  19. int WriteMessage(SOCKET , char *,int ) ;
  20. void Usage(char *progname) {
  21. fprintf(stderr,"Usagen%s -e [endpoint] -i [interface]n",
  22. progname);
  23. fprintf(stderr,"Where:n");
  24. fprintf(stderr,"tendpoint is the port to listen onn");
  25. fprintf(stderr,"tinterface is the ipaddr (in dotted decimal notation)");
  26. fprintf(stderr," to bind ton");
  27. fprintf(stderr,"Defaults are 5001 and INADDR_ANYn");
  28. WSACleanup();
  29. exit(1);
  30. }
  31. int main(int argc, char **argv) {
  32. char Buffer[128];
  33. char *interface= NULL;
  34. unsigned short port=DEFAULT_PORT;
  35. int fromlen;
  36. int i, ioctl_opt =1;
  37. struct sockaddr_in local, from;
  38. WSADATA wsaData;
  39. SOCKET listen_socket, msgsock;
  40. fd_set readfds, writefds, exceptfds;
  41. /* Parse arguments */
  42. if (argc >1) {
  43. for(i=1;i <argc;i++) {
  44. if ( (argv[i][0] == '-') || (argv[i][0] == '/') ) {
  45. switch(tolower(argv[i][1])) {
  46. case 'i':
  47. interface = argv[++i];
  48. break;
  49. case 'e':
  50. port = atoi(argv[++i]);
  51. break;
  52. default:
  53. Usage(argv[0]);
  54. break;
  55. }
  56. }
  57. else
  58. Usage(argv[0]);
  59. }
  60. }
  61. if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) {
  62. fprintf(stderr,"WSAStartup failed with error %dn",WSAGetLastError());
  63. WSACleanup();
  64. return -1;
  65. }
  66. if (port == 0){
  67. Usage(argv[0]);
  68. }
  69. //
  70. // The fd sets should be zeroed out before using them to prevent errors.
  71. FD_ZERO(&readfds);
  72. FD_ZERO(&writefds);
  73. FD_ZERO(&exceptfds);
  74. memset(Buffer,0,sizeof(Buffer));
  75. local.sin_family = AF_INET;
  76. //
  77. // bind to specific interface if desired.
  78. local.sin_addr.s_addr = (!interface)?INADDR_ANY:inet_addr(interface); 
  79. /* 
  80.  * Port MUST be in Network Byte Order
  81.  */
  82. local.sin_port = htons(port);
  83. listen_socket = socket(AF_INET, SOCK_STREAM,0); // TCP socket
  84. if (listen_socket == INVALID_SOCKET){
  85. fprintf(stderr,"socket() failed with error %dn",WSAGetLastError());
  86. WSACleanup();
  87. return -1;
  88. }
  89. //
  90. // bind() associates a local address and port combination with the
  91. // socket just created. 
  92. if (bind(listen_socket,(struct sockaddr*)&local,sizeof(local) ) 
  93. == SOCKET_ERROR) {
  94. fprintf(stderr,"bind() failed with error %dn",WSAGetLastError());
  95. WSACleanup();
  96. return -1;
  97. }
  98. //
  99. // start listening on the socket for incoming connections
  100. //
  101. if (listen(listen_socket,5) == SOCKET_ERROR) {
  102. fprintf(stderr,"listen() failed with error %dn",WSAGetLastError());
  103. WSACleanup();
  104. return -1;
  105. }
  106. printf("%s: Listening on port %dn",argv[0],port);
  107. //
  108. // Set the socket to non-blocking mode.
  109. //
  110. if (ioctlsocket(listen_socket,FIONBIO,&ioctl_opt) == SOCKET_ERROR) {
  111. fprintf(stderr,"ioctlsocket failed %dn",WSAGetLastError());
  112. WSACleanup();
  113. return -1;
  114. }
  115. //
  116. // The structure of the loop below is very simple. We only accept one
  117. // connection at a time. As soon as another client connects, we
  118. // disconnect the first one, and start talking to the new client.
  119. // All this server does is to echo the data received on the socket
  120. // back to the client.
  121. //
  122. // This is not a very realistic server, but it does serve to show that
  123. // select() does not scale very well on win32. If we were dealing
  124. // with more than one client, we would have to have a list of sockets
  125. // that are in each fdset to be able to check them when select()
  126. // returns.
  127. //
  128. while(1) {
  129. //
  130. // A socket in the listen() state becomes ready to read when a
  131. // client connects to it. An accept() will complete without
  132. // blocking.
  133. // Since select sets the sockets that are ready to be read from or
  134. // written to, we have to include listen_socket in the fdset each time
  135. // through the loop.
  136. //
  137. FD_SET(listen_socket,&readfds);
  138. i = select(0,&readfds,&writefds,&exceptfds,NULL);
  139. if (i == SOCKET_ERROR) {
  140. fprintf(stderr,"select failed %dn",WSAGetLastError());
  141. }
  142. if (i==0){
  143. fprintf(stderr,"Select returned no fds readyn");
  144. }
  145. if (FD_ISSET(listen_socket, &readfds)){
  146. //
  147. // close the previous client socket. 
  148. // We must also clear it from the fdset to prevent select()
  149. // from failing.
  150. //
  151. closesocket(msgsock);
  152. FD_CLR(msgsock,&readfds);
  153. FD_CLR(msgsock,&writefds);
  154. fromlen = sizeof(from);
  155. msgsock= accept(listen_socket,(struct sockaddr*)&from,&fromlen);
  156. if (msgsock == INVALID_SOCKET) {
  157. fprintf(stderr,"accept failed %dn",WSAGetLastError());
  158. WSACleanup();
  159. return -1;
  160. }
  161. FD_SET(msgsock,&writefds);
  162. FD_SET(msgsock,&readfds);
  163. continue;
  164. }
  165. if (FD_ISSET(msgsock,&readfds) ) {
  166. //
  167. // socket is ready to read, i.e., there is data on the socket.
  168. //
  169. if (ReadAndEcho(msgsock,Buffer,sizeof(Buffer))<0) {
  170. fprintf(stderr,"terminating connectionn");
  171. FD_CLR(msgsock,&readfds);
  172. FD_CLR(msgsock,&writefds);
  173. closesocket(msgsock);
  174. continue;
  175. }
  176. }
  177. if (FD_ISSET(msgsock,&writefds) ){
  178. if (WriteMessage(msgsock,Buffer,sizeof(Buffer)) <=0) {
  179. fprintf(stderr,"terminating connectionn");
  180. FD_CLR(msgsock,&readfds);
  181. FD_CLR(msgsock,&writefds);
  182. closesocket(msgsock);
  183. continue;
  184. }
  185. }
  186. FD_SET(msgsock,&writefds);
  187. FD_SET(msgsock,&readfds);
  188. }
  189. }
  190. int ReadAndEcho(SOCKET insock, char *Buffer,int size) {
  191. int rc;
  192. rc = recv(insock,Buffer,size,0);
  193. if (rc == SOCKET_ERROR) {
  194. fprintf(stderr,"recv() failed with error %dn",WSAGetLastError());
  195. return -1;
  196. }
  197. if (rc ==0) {
  198. fprintf(stderr,"Connection closed by clientn");
  199. return 0;
  200. }
  201. printf("Received [%s] from clientn",Buffer);
  202. return rc;
  203. }
  204. int WriteMessage(SOCKET outsock, char *Buffer,int size) {
  205. int rc;
  206. int lasterr;
  207. printf("Sending [%s] to clientn",Buffer);
  208. rc = send(outsock,Buffer,size, 0);
  209. if (rc == SOCKET_ERROR) {
  210.   lasterr = WSAGetLastError();
  211.   if (lasterr == WSAEWOULDBLOCK)
  212. return 0;
  213.   else {
  214. fprintf(stderr,"send() failed with error %dn",lasterr);
  215. return -1;
  216.   }
  217. }
  218. if (rc ==0) {
  219. fprintf(stderr,"Connection closed by clientn");
  220. }
  221. return rc;
  222. }