Server.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #include "Server.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/socket.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <sys/types.h>
  10. #include <signal.h>
  11. #include "SocketUtils.h"
  12. void serverInitDefaults(Server* s)
  13. {
  14. s->maxClients = -1;
  15. s->port = -1;
  16. s->threads = NULL;
  17. s->clientSockets = NULL;
  18. s->clientUser = NULL;
  19. s->connectSocket = -1;
  20. s->handler = NULL;
  21. s->directory = NULL;
  22. }
  23. int serverInit(Server* s, int maxClients, short port, char* directory)
  24. {
  25. s->maxClients = maxClients;
  26. s->port = port;
  27. s->directory = directory;
  28. if(chdir(directory) == -1)
  29. {
  30. perror("cannot change directory");
  31. serverRemove(s);
  32. return -1;
  33. }
  34. // initialize storage for clients
  35. s->threads = malloc(sizeof(pthread_t) * maxClients);
  36. s->clientSockets = malloc(sizeof(int) * maxClients);
  37. s->clientUser = malloc(sizeof(char*) * maxClients);
  38. for(int i = 0; i < maxClients; i++)
  39. {
  40. s->threads[i] = -1;
  41. s->clientSockets[i] = -1;
  42. s->clientUser[i] = NULL;
  43. }
  44. // create the socket for clients to connect
  45. s->connectSocket = socket(AF_INET, SOCK_STREAM, 0);
  46. if(s->connectSocket == -1)
  47. {
  48. perror("Cannot create socket");
  49. serverRemove(s);
  50. return -1;
  51. }
  52. // prevents clients from blocking the port if the server exits
  53. struct linger sl;
  54. sl.l_onoff = 1;
  55. sl.l_linger = 0;
  56. if(setsockopt(s->connectSocket, SOL_SOCKET, SO_LINGER, &sl, sizeof(struct linger)) == -1)
  57. {
  58. perror("Cannot set non lingering");
  59. serverRemove(s);
  60. return -1;
  61. }
  62. // specifies data of the port and binds it
  63. struct sockaddr_in connectSocketData;
  64. memset(&connectSocketData, 0, sizeof(struct sockaddr_in));
  65. connectSocketData.sin_family = AF_INET;
  66. connectSocketData.sin_addr.s_addr = INADDR_ANY;
  67. connectSocketData.sin_port = htons(port);
  68. if(bind(s->connectSocket, (struct sockaddr*) &connectSocketData, sizeof(struct sockaddr_in)) != 0)
  69. {
  70. perror("Cannot bind socket");
  71. serverRemove(s);
  72. return -1;
  73. }
  74. // mark this socket as handler for connection requests
  75. if(listen(s->connectSocket, 5) != 0)
  76. {
  77. perror("Cannot start listening");
  78. serverRemove(s);
  79. return -1;
  80. }
  81. return 0;
  82. }
  83. void serverRemove(Server* s)
  84. {
  85. s->port = -1;
  86. if(s->threads != NULL)
  87. {
  88. for(int i = 0; i < s->maxClients; i++)
  89. {
  90. if(s->threads[i] != -1)
  91. {
  92. printf("%d thread\n", i);
  93. pthread_cancel(s->threads[i]);
  94. pthread_join(s->threads[i], NULL);
  95. }
  96. }
  97. free(s->threads);
  98. s->threads = NULL;
  99. }
  100. if(s->clientSockets != NULL)
  101. {
  102. for(int i = 0; i < s->maxClients; i++)
  103. {
  104. if(s->clientSockets[i] != -1)
  105. {
  106. if(close(s->clientSockets[i]) == -1)
  107. {
  108. printf("%d", i);
  109. perror(" cannot close client socket");
  110. }
  111. else
  112. {
  113. printf("%d closed\n", i);
  114. }
  115. }
  116. }
  117. free(s->clientSockets);
  118. s->clientSockets = NULL;
  119. }
  120. if(s->clientUser != NULL)
  121. {
  122. for(int i = 0; i < s->maxClients; i++)
  123. {
  124. if(s->clientUser[i] != NULL)
  125. {
  126. free(s->clientUser[i]);
  127. s->clientUser[i] = NULL;
  128. }
  129. }
  130. free(s->clientUser);
  131. s->clientUser = NULL;
  132. }
  133. s->maxClients = -1;
  134. if(s->connectSocket != -1)
  135. {
  136. if(close(s->connectSocket) != 0)
  137. {
  138. perror("Cannot close server socket");
  139. }
  140. else
  141. {
  142. printf("connection listener closed\n");
  143. }
  144. s->connectSocket = -1;
  145. }
  146. s->handler = NULL;
  147. }
  148. static void* clientHandler(void* data)
  149. {
  150. int id = ((ThreadData*) data)->id;
  151. Server* s = ((ThreadData*) data)->server;
  152. Stream in;
  153. while(1)
  154. {
  155. streamInit(&in, 1024);
  156. int size = receiveAll(s->clientSockets[id], &in);
  157. if(size > 0)
  158. {
  159. if(s->handler(id, s->clientSockets[id], &in))
  160. {
  161. break;
  162. }
  163. }
  164. else if(size == 0)
  165. {
  166. printf("Client %d closed remote socket\n", id);
  167. streamRemove(&in);
  168. break;
  169. }
  170. else
  171. {
  172. perror("recv error");
  173. streamRemove(&in);
  174. break;
  175. }
  176. streamRemove(&in);
  177. }
  178. if(close(s->clientSockets[id]) != 0)
  179. {
  180. printf("%d", id);
  181. perror(" cannot close client socket");
  182. }
  183. else
  184. {
  185. printf("%d closed\n", id);
  186. }
  187. serverFreeUser(s, id);
  188. s->clientSockets[id] = -1;
  189. return NULL;
  190. }
  191. int serverSend(int clientSocket, Stream* out)
  192. {
  193. if(sendAll(clientSocket, out) == -1)
  194. {
  195. return -1;
  196. }
  197. return 0;
  198. }
  199. void serverWaitForConnection(Server* s)
  200. {
  201. socklen_t addrlen = sizeof(struct sockaddr_in);
  202. while(1)
  203. {
  204. printf("Waiting for connections...\n");
  205. struct sockaddr_in clientSocketData;
  206. int clientSocket = accept(s->connectSocket, (struct sockaddr*) &clientSocketData, &addrlen);
  207. if(clientSocket >= 0)
  208. {
  209. printf("Client connected from %s:%d...\n", inet_ntoa(clientSocketData.sin_addr), (int) ntohs(clientSocketData.sin_port));
  210. int i = 0;
  211. while(1)
  212. {
  213. if(s->clientSockets[i] == -1)
  214. {
  215. if(s->threads[i] != -1)
  216. {
  217. pthread_cancel(s->threads[i]);
  218. pthread_join(s->threads[i], NULL);
  219. }
  220. ThreadData data;
  221. data.id = i;
  222. data.server = s;
  223. if(pthread_create(&s->threads[i], NULL, clientHandler, (void*) &data) != 0)
  224. {
  225. perror("Cannot create thread");
  226. Stream out;
  227. streamInit(&out, 16);
  228. streamWriteChar(&out, -1);
  229. streamWriteChars(&out, "Cannot create thread\n");
  230. serverSend(clientSocket, &out);
  231. streamRemove(&out);
  232. close(clientSocket);
  233. }
  234. else
  235. {
  236. s->clientSockets[i] = clientSocket;
  237. Stream out;
  238. streamInit(&out, 64);
  239. streamWriteChar(&out, 1);
  240. streamWriteChars(&out, "Welcome to the server, please enter one of these commands:\n");
  241. streamWriteChars(&out, "- HELP\n");
  242. streamWriteChars(&out, "- SEND\n");
  243. streamWriteChars(&out, "- LIST\n");
  244. streamWriteChars(&out, "- READ\n");
  245. streamWriteChars(&out, "- DEL\n");
  246. streamWriteChars(&out, "- QUIT\n");
  247. if(serverSend(clientSocket, &out) == -1)
  248. {
  249. perror("Cannot send welcome message");
  250. close(clientSocket);
  251. s->clientSockets[i] = -1;
  252. }
  253. streamRemove(&out);
  254. }
  255. break;
  256. }
  257. i++;
  258. if(i >= s->maxClients)
  259. {
  260. printf("max clients reached\n");
  261. Stream out;
  262. streamInit(&out, 16);
  263. streamWriteChar(&out, -1);
  264. streamWriteChars(&out, "the server is full\n");
  265. serverSend(clientSocket, &out);
  266. streamRemove(&out);
  267. close(clientSocket);
  268. break;
  269. }
  270. }
  271. }
  272. }
  273. }
  274. void serverRegisterHandler(Server* s, ServerStreamFunction f)
  275. {
  276. s->handler = f;
  277. }
  278. int serverSetUser(Server* s, int clientId, char* name)
  279. {
  280. if(clientId < 0 || clientId >= s->maxClients)
  281. {
  282. return -1;
  283. }
  284. int l = strlen(name) + 1;
  285. s->clientUser[clientId] = malloc(sizeof(char) * l);
  286. strncpy(s->clientUser[clientId], name, l);
  287. return 0;
  288. }
  289. char* serverGetUser(Server* s, int clientId)
  290. {
  291. if(clientId < 0 || clientId >= s->maxClients)
  292. {
  293. return NULL;
  294. }
  295. return s->clientUser[clientId];
  296. }
  297. void serverFreeUser(Server* s, int clientId)
  298. {
  299. if(clientId < 0 || clientId >= s->maxClients)
  300. {
  301. return;
  302. }
  303. if(s->clientUser[clientId] != NULL)
  304. {
  305. free(s->clientUser[clientId]);
  306. s->clientUser[clientId] = NULL;
  307. }
  308. }