/udp_chat_server/Server.c

https://bitbucket.org/schnika/chat-server-client · C · 475 lines · 363 code · 79 blank · 33 comment · 59 complexity · 6c384b95d68d0c41628c9526d1d04dc0 MD5 · raw file

  1. #include "Server.h"
  2. /* accept or decline a connection request.
  3. * A new user gets accepted when the choosen name is not in the user list
  4. */
  5. void
  6. sendSV_CON_REP()
  7. {
  8. ID = 2;
  9. uint8_t accepted = 1;
  10. uint16_t name_length;
  11. memcpy(&name_length, CL_CON_REQ + 1, sizeof(uint16_t));
  12. name_length = ntohs(name_length);
  13. char *name = malloc(name_length);
  14. strncpy(name, CL_CON_REQ + 3, name_length);
  15. /* Check if username already in list */
  16. if(find_username(name) == 1)
  17. {
  18. add_user(name);
  19. accepted = 0;
  20. }else accepted = 1;
  21. SV_CON_REP = malloc(sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint16_t));
  22. memcpy(SV_CON_REP, &ID, sizeof(uint8_t));
  23. memcpy(SV_CON_REP + 1, &accepted, sizeof(uint8_t));
  24. uint16_t cl_port = user->new_sv_sock_addr.sin_port;
  25. memcpy(SV_CON_REP + 2, &cl_port, sizeof(uint16_t));
  26. err = sendto(server_socket, SV_CON_REP, 4, 0, &from, sizeof(struct sockaddr_in));
  27. if (err == -1)
  28. printf("ERROR: Cannot send SV_CON_REP to client.\n");
  29. if(accepted == 0)
  30. {
  31. sendSV_CON_AMSG();
  32. }
  33. }
  34. /* inform all users about the new client */
  35. void
  36. sendSV_CON_AMSG()
  37. {
  38. ID = 3;
  39. SV_CON_AMSG = malloc(strlen(user->name)+3);
  40. uint16_t name_length = htons(strlen(user->name));
  41. memcpy(SV_CON_AMSG, &ID, sizeof(uint8_t));
  42. memcpy(SV_CON_AMSG + 1, &name_length, sizeof(uint16_t));
  43. strncpy(SV_CON_AMSG + 3, user->name, strlen(user->name));
  44. sendToAll(SV_CON_AMSG, 3 + strlen(user->name));
  45. }
  46. /* build a recieved user message end send it to all users */
  47. void
  48. sendSV_AMSG(struct user *sender)
  49. {
  50. ID = 5;
  51. uint16_t name_length = htons(strlen(sender->name));
  52. uint32_t msg_length;
  53. memcpy(&msg_length, CL_MSG+1, sizeof(uint32_t));
  54. msg_length = ntohl(msg_length);
  55. char *msg = malloc(msg_length);
  56. strncpy(msg, CL_MSG+5, msg_length);
  57. SV_AMSG = malloc(7 + strlen(msg) + strlen(sender->name));
  58. msg_length = htonl(msg_length);
  59. memcpy(SV_AMSG, &ID, 1);
  60. memcpy(SV_AMSG+1, &name_length, 2);
  61. memcpy(SV_AMSG+3, sender->name, strlen(sender->name));
  62. memcpy(SV_AMSG+3+strlen(sender->name), &msg_length, 4);
  63. memcpy(SV_AMSG+7+strlen(sender->name), msg, ntohl(msg_length));
  64. sendToAll(SV_AMSG, 7 + strlen(sender->name) + ntohl(msg_length));
  65. }
  66. /* build char* SV_DISC_REP as response to CL_DISC_REQ */
  67. void
  68. sendSV_DISC_REP(struct user *sender)
  69. {
  70. ID = 7;
  71. SV_DISC_REP = malloc(1);
  72. memcpy(SV_DISC_REP, &ID, 1);
  73. int count;
  74. for (count = 0; count < 2; count ++)
  75. {
  76. to.sin_family = AF_INET;
  77. to.sin_port = htons(sender->port);
  78. to.sin_addr.s_addr = inet_addr(sender->IP);
  79. err = sendto(sender->sv_socket, SV_DISC_REP, 1, 0, &to, sizeof(struct sockaddr_in));
  80. if (err == -1)
  81. {
  82. printf("ERROR: Cannot send SV_DISC_REP to client.\n");
  83. count += 1;
  84. sleep(5);
  85. }
  86. else
  87. sendSV_DISC_AMSG(sender->name);
  88. remove_user(sender);
  89. break;
  90. }
  91. }
  92. /* build char *SV_DISC_AMSG to inform about client disconnect */
  93. void
  94. sendSV_DISC_AMSG(char *name)
  95. {
  96. ID = 8;
  97. uint16_t name_length;
  98. name_length = strlen(name);
  99. name_length = htons(name_length);
  100. SV_DISC_AMSG = malloc(3 + strlen(name));
  101. memcpy(SV_DISC_AMSG, &ID, 1);
  102. memcpy(SV_DISC_AMSG+1, &name_length, 2);
  103. strncpy(SV_DISC_AMSG+3, name, strlen(name));
  104. sendToAll(SV_DISC_AMSG, 3 + strlen(name));
  105. }
  106. /* send messages to all users in the list */
  107. void
  108. sendToAll(char *msg, int msg_length)
  109. {
  110. struct user *receiver = user;
  111. int i;
  112. for (i = 0; i < usercount; i++)
  113. {
  114. to.sin_family = AF_INET;
  115. to.sin_port = htons(receiver->port);
  116. to.sin_addr.s_addr = inet_addr(receiver->IP);
  117. err = sendto(receiver->sv_socket, msg, msg_length, 0, &to, sizeof(struct sockaddr_in));
  118. if (err == -1)
  119. printf("ERROR: Cannot send msg (ID: %i) to client.\n", atoi(msg[0]));
  120. receiver = receiver->next;
  121. }
  122. }
  123. /* remove user from list, clear the associated socket and free allocated space */
  124. void
  125. remove_user(struct user *leaver)
  126. {
  127. struct user *tmp;
  128. tmp = user;
  129. int i;
  130. for (i = 0; i < usercount; i++)
  131. {
  132. if(tmp->name == leaver->name)
  133. {
  134. close(tmp->sv_socket);
  135. free(tmp);
  136. usercount --;
  137. break;
  138. }
  139. else if (tmp->next->name == leaver->name)
  140. {
  141. tmp->next = leaver->next;
  142. close(leaver->sv_socket);
  143. free(tmp->next);;
  144. usercount --;
  145. break;
  146. }
  147. else
  148. tmp = tmp->next;
  149. }
  150. }
  151. /*
  152. * checks wether username exists
  153. * @param name - the username to look for
  154. * return 1 - username doesn't exist
  155. * return 0 - username already exists
  156. */
  157. int
  158. find_username(char *name)
  159. {
  160. struct user *tmp = malloc(sizeof(struct user *));
  161. if(usercount == 0)
  162. {
  163. return 1;
  164. }
  165. else
  166. {
  167. tmp = user;
  168. while(tmp->next != NULL)
  169. {
  170. if(strncmp(tmp->name, name, strnlen(name)) == 0)
  171. {
  172. return 0;
  173. }
  174. tmp = tmp->next;
  175. }
  176. return 1;
  177. }
  178. }
  179. /* add user
  180. * @param name = username of the new_user user
  181. */
  182. void
  183. add_user(char *name)
  184. {
  185. new_user = malloc(sizeof(struct user));
  186. // set name
  187. strncpy(new_user->name, name, strlen(name));
  188. new_user->rep_counter;
  189. new_user->sv_socket = socket(AF_INET, SOCK_DGRAM, 0);
  190. strncpy(new_user->IP,inet_ntoa(from.sin_addr), strlen(inet_ntoa(from.sin_addr)));
  191. new_user->port = ntohs(from.sin_port);
  192. struct sockaddr_in sv_sock_add;
  193. sv_sock_add.sin_family = AF_INET;
  194. sv_sock_add.sin_port = 0;
  195. sv_sock_add.sin_addr.s_addr = inet_addr("127.0.0.1");
  196. new_user->new_sv_sock_addr = sv_sock_add;
  197. /* new_user port for the new_user client socket */
  198. err = bind(new_user->sv_socket, (struct sockaddr *) &new_user->new_sv_sock_addr, sizeof(struct sockaddr_in));
  199. if(err < 0)
  200. {
  201. perror("Bind error");
  202. }
  203. // set next user
  204. new_user->next = user;
  205. user = new_user;
  206. usercount += 1;
  207. }
  208. /* Portnumber validation */
  209. int
  210. isValidPort(char *str)
  211. {
  212. in_port_t tmp_port;
  213. tmp_port = atoi(str);
  214. if(tmp_port < 1024 || tmp_port > 65535)
  215. {
  216. printf("Invalid port number. Port hast do be between 1024 and 65535.\n");
  217. return 0;
  218. }
  219. printf("Valid port: %u\n", tmp_port);
  220. return 1;
  221. }
  222. /* Initialize field descriptors */
  223. void
  224. init_fds()
  225. {
  226. FD_ZERO(&readset);
  227. FD_SET(server_socket, &readset);
  228. struct user *tmp;
  229. tmp = user;
  230. highsock = server_socket;
  231. int i;
  232. for (i = 0; i<usercount; i++)
  233. {
  234. FD_SET(tmp->sv_socket, &readset);
  235. if (tmp->sv_socket > highsock)
  236. highsock = tmp->sv_socket;
  237. tmp = tmp->next;
  238. }
  239. }
  240. int main(int argc, char**argv)
  241. {
  242. /* Init user */
  243. user = malloc(sizeof(struct user));
  244. user = NULL;
  245. usercount = 0;
  246. time_to_wait = malloc(sizeof(struct timeval *));
  247. time_to_wait->tv_sec = 5;
  248. time_to_wait->tv_usec = 0;
  249. struct timeval *time_now = malloc(sizeof(struct timeval *));
  250. struct timeval *last_res = malloc(sizeof(struct timeval *));
  251. struct timeval *time_diff = malloc(sizeof(struct timeval *));
  252. int error;
  253. int flen;
  254. int rep_len;
  255. int c;
  256. int index;
  257. opterr = 0;
  258. while ((c = getopt(argc, argv, "p:")) != -1)
  259. switch(c)
  260. {
  261. case 'p':
  262. if (isValidPort(optarg) != 0)
  263. {
  264. serv_port = atoi(optarg);
  265. break;
  266. }
  267. return 1;
  268. case '?':
  269. if (optopt == 'p')
  270. fprintf (stderr, "Option -%c requires an argument.\n", optopt);
  271. else if (isprint (optopt))
  272. fprintf (stderr, "Unknown option `-%c'.\n", optopt);
  273. else
  274. fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
  275. return 1;
  276. default:
  277. abort ();
  278. }
  279. server_socket = socket(AF_INET, SOCK_DGRAM, 0);
  280. if (server_socket < 1)
  281. {
  282. perror("Create socket");
  283. } printf("Socket created!\n");
  284. /* set port and ip*/
  285. server_socket_address.sin_family = AF_INET;
  286. server_socket_address.sin_port = htons(serv_port);
  287. server_socket_address.sin_addr.s_addr = inet_addr("127.0.0.1");
  288. printf("IP Adresse: %s Port: %u\n", inet_ntoa(server_socket_address.sin_addr), ntohs(server_socket_address.sin_port));
  289. error = bind(server_socket, (struct sockaddr *) &server_socket_address, sizeof(struct sockaddr_in));
  290. if(error < 0)
  291. {
  292. perror("Bind error");
  293. } else printf("Socket bound!\n");
  294. int res;
  295. int sock;
  296. time_now->tv_sec = time(NULL);
  297. while(1)
  298. {
  299. ID = 0;
  300. init_fds();
  301. cl_rep_buffer = malloc(64);
  302. res = select(highsock + 1, &readset, NULL, NULL, time_to_wait);
  303. /* select error*/
  304. if (res == -1)
  305. {
  306. perror("Select Error.");
  307. }
  308. /* timeout. increase rep_counter for each connected user */
  309. else if (res == 0)
  310. {
  311. time_to_wait->tv_sec = 5;
  312. ID = 9;
  313. SV_PING_REQ = malloc(1);
  314. memcpy(SV_PING_REQ, &ID, sizeof(uint8_t));
  315. struct user *tmp;
  316. tmp = user;
  317. int i;
  318. for(i = 0; i<usercount; i++)
  319. {
  320. sendToAll(SV_PING_REQ, 1);
  321. tmp->rep_counter += 1;
  322. if(tmp->rep_counter == 4)
  323. {
  324. printf("Verbindung zu User %s unterbrochen. Nutzr wird vom Server entfernt.\n", tmp->name);
  325. remove_user(tmp);
  326. }
  327. }
  328. }
  329. else if (res > 0)
  330. {
  331. last_res->tv_sec = time(NULL);
  332. /* calc time diff */
  333. timersub(time_now, last_res, time_diff);
  334. timersub(time_to_wait, time_diff, time_to_wait);
  335. if (FD_ISSET(server_socket, &readset))
  336. {
  337. rep_len = recvfrom(server_socket, cl_rep_buffer, 64, 0, (struct sockaddr*) &from, &flen);
  338. memcpy(&ID, cl_rep_buffer, sizeof(uint8_t));
  339. if (ID == 1)
  340. {
  341. printf("Anfrage gestellt.\n");
  342. CL_CON_REQ = malloc(rep_len);
  343. memcpy(CL_CON_REQ, cl_rep_buffer, rep_len);
  344. sendSV_CON_REP();
  345. }
  346. else
  347. {
  348. printf("Falsche Anfrage gestellt.\n");
  349. }
  350. }
  351. struct user *tmp;
  352. tmp = user;
  353. int i;
  354. for (i = 0; i < usercount; i++)
  355. {
  356. if(FD_ISSET(tmp->sv_socket, &readset))
  357. {
  358. rep_len = recvfrom(tmp->sv_socket, cl_rep_buffer, 64, 0, (struct sockaddr*) &from, &flen);
  359. if(rep_len < 0)
  360. break;
  361. memcpy(&ID, cl_rep_buffer, sizeof(uint8_t));
  362. switch(ID)
  363. {
  364. /* CL_MSG */
  365. case 4:
  366. {
  367. CL_MSG = malloc(rep_len);
  368. memcpy(CL_MSG, cl_rep_buffer, rep_len);
  369. sendSV_AMSG(tmp);
  370. break;
  371. }
  372. /* CL_DISC_REQ */
  373. case 6:
  374. {
  375. CL_DISC_REQ = malloc(rep_len);
  376. memcpy(CL_DISC_REQ, cl_rep_buffer, rep_len);
  377. sendSV_DISC_REP(tmp);
  378. break;
  379. }
  380. /* CL_PING_REP */
  381. case 10:
  382. {
  383. // reset rep_counter
  384. tmp->rep_counter = 0;
  385. }
  386. default:
  387. {
  388. break;
  389. }
  390. }
  391. }
  392. tmp = tmp->next;
  393. }
  394. }
  395. }
  396. }