Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.31 KB | None | 0 0
  1. // Nazwa modu³u: Server.c
  2. //
  3. // Opis:
  4. // Prosta aplikacja serwera TCP, akceptuj¹ca nachodz¹ce
  5. // po³¹czenia klientów. Po ustanowieniu po³¹czenia
  6. // uruchamiany jest w¹tek odczytuj¹cy dane przes³ane przez
  7. // klienta i odsy³aj¹cy je z powrotem.
  8. //
  9. // Opcje wiersza poleceñ:
  10. // server [-p:port] [-i:IP]
  11. // -p:port Numer nas³uchuj¹cego portu
  12. // -i:IP Nas³uchuj¹cy interfejs
  13. //
  14. #include <winsock2.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17.  
  18. #define DEFAULT_PORT 5150
  19. #define DEFAULT_BUFFER 4096
  20.  
  21. int iPort = DEFAULT_PORT; // Port nas³uchuj¹cy klientów
  22. BOOL setInterface = FALSE; // Czy okreœlono interfejs s³uchaj¹cy?
  23. char szAddress[128];
  24. char szMessage[1024];
  25. char szBuffer[2048]; // Interfejs nas³uchuj¹cy klientów
  26.  
  27. //
  28. // Funkcja: usage
  29. //
  30. // Opis:
  31. // Wydruk informacji o dzia³aniu programu
  32. //
  33.  
  34. void usage()
  35. {
  36. printf("u¿ycie: server [-p:port] [-i:IP]\n\n");
  37. printf(" -p:port Numer nas³uchuj¹cego portu\n");
  38. printf(" -i:IP Nas³uchuj¹cy interfejs\n");
  39. ExitProcess(1);
  40. }
  41.  
  42. //
  43. // Funkcja: ValidateArgs
  44. //
  45. // Opis:
  46. // Analiza argumentów wiersza poleceñ i ustalenie wartoœci
  47. // niektórych znaczników globalnych, decyduj¹cych o wykonaniu
  48. // okreœlonych czynnoœci.
  49. //
  50. void ValidateArgs(int argc, char **argv)
  51. {
  52. int i;
  53.  
  54. for(i = 1; i < argc; i++)
  55. {
  56. if ((argv[i][0] == '-') || (argv[i][0] == '/'))
  57. {
  58. switch (argv[i][1])
  59. {
  60. case 'p':
  61. iPort = atoi(&argv[i][3]);
  62. break;
  63. case 'i':
  64. setInterface = TRUE;
  65. if (strlen(argv[i]) > 3)
  66. strcpy(szAddress, &argv[i][3]);
  67. break;
  68. default:
  69. usage();
  70. break;
  71. }
  72. }
  73. }
  74. }
  75.  
  76. //
  77. // Funkcja: ClientProcedure
  78. //
  79. // Opis:
  80. // Ta funkcja jest wywo³ywana w postaci w¹tku obs³uguj¹cego
  81. // dane po³¹czenie klienta. Przekazany parametr jest uchwytem
  82. // gniazda zwróconym przez wywo³anie funkcji accept(). Ta
  83. // funkcja czyta dane nades³ane przez klienta i odsy³a je
  84. // z powrotem.
  85. //
  86. DWORD WINAPI ClientProcedure(LPVOID lpParam)
  87. {
  88. SOCKET sock=(SOCKET)lpParam;
  89. char szBuff[DEFAULT_BUFFER];
  90. int ret,
  91. nLeft,
  92. idx;
  93.  
  94. while(1)
  95. {
  96. // Wykonanie blokuj¹cej funkcji recv ()
  97. //
  98. ret = recv(sock, szBuff, DEFAULT_BUFFER, 0);
  99. if (ret == 0) // Zamkniêcie uzgodnione
  100. break;
  101. else if (ret == SOCKET_ERROR)
  102. {
  103. printf("Funkcja recv() zakoñczona b³êdem: %d\n",
  104. WSAGetLastError());
  105. break;
  106. }
  107. szBuff[ret] = '\0';
  108. printf("ODBIÓR: '%s'\n", szBuff);
  109. /*
  110. // Odes³anie danych
  111. //
  112. nLeft = ret;
  113. idx = 0;
  114. // Sprawdzenie, czy zapisaliœmy wszystkie dane
  115. //
  116. while(nLeft > 0)
  117. {
  118. ret = send(sock, &szBuff[idx], nLeft, 0);
  119. if (ret == 0)
  120. break;
  121. else if (ret == SOCKET_ERROR)
  122. {
  123. printf("Funkcja send() zakoñczona"
  124. " b³êdem: %d\n",
  125. WSAGetLastError());
  126. break;
  127. }
  128. nLeft -= ret;
  129. idx += ret;
  130. }*/
  131. }
  132. return 0;
  133. }
  134.  
  135. DWORD WINAPI WriterProcedure(LPVOID lpParam)
  136. {
  137. SOCKET sClient=(SOCKET)lpParam;
  138. char szBuff[DEFAULT_BUFFER];
  139. int ret,
  140. nLeft,
  141. idx;
  142.  
  143. while(1)
  144. {
  145.  
  146. scanf("%s", szMessage);
  147. int i = 0;
  148.  
  149. ret = send(sClient, szMessage, strlen(szMessage), 0);
  150. if (ret == 0)
  151. break;
  152. else if (ret == SOCKET_ERROR)
  153. {
  154. printf("Funkcja send() zakoñczona b³êdem: %d\n",
  155. WSAGetLastError());
  156. break;
  157. }
  158. printf("Wys³ano %d bajtów\n", ret);
  159.  
  160. }
  161. return 0;
  162. }
  163.  
  164. //
  165. // Funkcja: main
  166. //
  167. // Opis:
  168. // W¹tek g³ówny. Inicjacja interfejsu Winsock, analiza
  169. // argumentów wiersza poleceñ, utworzenie nas³uchuj¹cego
  170. // gniazda, zwi¹zanie go z adresem lokalnym i oczekiwanie
  171. // na po³¹czenia klientów.
  172. //
  173. int main(int argc, char **argv)
  174. {
  175. WSADATA wsd;
  176. SOCKET sListen,
  177. sClient;
  178. struct sockaddr_in local,
  179. client;
  180. int iAddrSize;
  181. HANDLE hThread;
  182. HANDLE hThread2;
  183. DWORD dwThreadId;
  184. DWORD dwThreadId2;
  185.  
  186.  
  187. ValidateArgs(argc, argv);
  188. if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
  189. {
  190. printf("Nie mo¿na wczytaæ biblioteki Winsock!\n");
  191. return 1;
  192. }
  193. // Utworzenie nas³uchuj¹cego gniazda
  194. //
  195. sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  196. if (sListen == SOCKET_ERROR)
  197. {
  198. printf("Funckja socket() zakoñczona b³êdem: %d\n",
  199. WSAGetLastError());
  200. return 1;
  201. }
  202. // Wybór lokalnego interfejsu, z którym zostanie
  203. // zwi¹zane gniazdo
  204. //
  205. if (setInterface) // jeœli okreœlono interfejs, s³uchaj na nim
  206. {
  207. local.sin_addr.s_addr = inet_addr(szAddress);
  208. //if (local.sin_addr.s_addr == INADDR_NONE)
  209. // usage();
  210. }
  211. else // jeœli nie okreœlono interfejsu, to s³uchaj na wszystkich
  212. {
  213. local.sin_addr.s_addr = htonl(INADDR_ANY);
  214. }
  215.  
  216. local.sin_family = AF_INET;
  217. local.sin_port = htons((u_short)iPort);
  218.  
  219. if (bind(sListen, (struct sockaddr *)&local,
  220. sizeof(local)) == SOCKET_ERROR)
  221. {
  222. printf("Funkcja bind() zakoñczona b³êdem: %d\n",
  223. WSAGetLastError());
  224. return 1;
  225. }
  226. listen(sListen, 8);
  227. //
  228. // Oczekiwanie na ¿¹dania klientów w ci¹g³ej pêtli. Po
  229. // wykryciu próby po³¹czenia, utworzenie w¹tku i przekazanie
  230. // jego uchwytu.
  231. //
  232.  
  233. while (1)
  234. {
  235. iAddrSize = sizeof(client);
  236. sClient = accept(sListen, (struct sockaddr *)&client,
  237. &iAddrSize);
  238. if (sClient == INVALID_SOCKET)
  239. {
  240. printf("Funkcja accept() zakoñczona b³êdem: %d\n",
  241. WSAGetLastError());
  242. break;
  243. }
  244. printf("Zaakceptowano klienta: %s:%d\n",
  245. inet_ntoa(client.sin_addr), ntohs(client.sin_port));
  246.  
  247. hThread = CreateThread(NULL, 0, ClientProcedure,
  248. (LPVOID)sClient, 0, &dwThreadId);
  249. if (hThread == NULL)
  250. {
  251. printf("Funkcja CreateThread() zakoñczona b³êdem: %d\n",
  252. WSAGetLastError());
  253. break;
  254. }
  255. hThread2 = CreateThread(NULL, 0, WriterProcedure,
  256. (LPVOID)sClient, 0, &dwThreadId2);
  257. if (hThread2 == NULL)
  258. {
  259. printf("Funkcja CreateThread() zakoñczona b³êdem: %d\n",
  260. WSAGetLastError());
  261. break;
  262. }
  263. CloseHandle(hThread); // zwalnia uchwyt, nie powoduje zakonczenia watku
  264. CloseHandle(hThread2);
  265. }
  266. closesocket(sListen);
  267.  
  268. WSACleanup();
  269. return 0;
  270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement