Advertisement
Guest User

Untitled

a guest
Mar 19th, 2017
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.86 KB | None | 0 0
  1. /*
  2. * Copyright 2014
  3. *
  4. * Author: Dinux
  5. * Description: Simple chatroom in C
  6. * Version: 1.0
  7. *
  8. */
  9.  
  10. #include <sys/socket.h>
  11. #include <netinet/in.h>
  12. #include <arpa/inet.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <unistd.h>
  16. #include <errno.h>
  17. #include <string.h>
  18. #include <pthread.h>
  19. #include <sys/types.h>
  20.  
  21. #define MAX_CLIENTS 100
  22.  
  23. static unsigned int cli_count = 0;
  24. static int uid = 10;
  25.  
  26. char **usernames = {"paul","andrei","cipri","truta"};
  27. char **passwords = {"1","1","1","1"};
  28. int userCount = 4;
  29.  
  30. int checkLogin(char *username,char *passoword){
  31. int i;
  32. for(i=0;i<n;i++)
  33. if(!strcmp(username,usernames[i])&&!strcmp(password,passwords[i]))
  34. return 1;
  35. return 0;
  36. }
  37.  
  38. /* Client structure */
  39. typedef struct {
  40. struct sockaddr_in addr; /* Client remote address */
  41. int connfd; /* Connection file descriptor */
  42. int uid; /* Client unique identifier */
  43. char name[32]; /* Client name */
  44. } client_t;
  45.  
  46. client_t *clients[MAX_CLIENTS];
  47.  
  48. /* Add client to queue */
  49. void queue_add(client_t *cl){
  50. int i;
  51. for(i=0;i<MAX_CLIENTS;i++){
  52. if(!clients[i]){
  53. clients[i] = cl;
  54. return;
  55. }
  56. }
  57. }
  58.  
  59. /* Delete client from queue */
  60. void queue_delete(int uid){
  61. int i;
  62. for(i=0;i<MAX_CLIENTS;i++){
  63. if(clients[i]){
  64. if(clients[i]->uid == uid){
  65. clients[i] = NULL;
  66. return;
  67. }
  68. }
  69. }
  70. }
  71.  
  72. /* Send message to all clients but the sender */
  73. void send_message(char *s, int uid){
  74. int i;
  75. for(i=0;i<MAX_CLIENTS;i++){
  76. if(clients[i]){
  77. if(clients[i]->uid != uid){
  78. write(clients[i]->connfd, s, strlen(s));
  79. }
  80. }
  81. }
  82. }
  83.  
  84. /* Send message to all clients */
  85. void send_message_all(char *s){
  86. int i;
  87. for(i=0;i<MAX_CLIENTS;i++){
  88. if(clients[i]){
  89. write(clients[i]->connfd, s, strlen(s));
  90. }
  91. }
  92. }
  93.  
  94. /* Send message to sender */
  95. void send_message_self(const char *s, int connfd){
  96. write(connfd, s, strlen(s));
  97. }
  98.  
  99. /* Send message to client */
  100. void send_message_client(char *s, int uid){
  101. int i;
  102. for(i=0;i<MAX_CLIENTS;i++){
  103. if(clients[i]){
  104. if(clients[i]->uid == uid){
  105. write(clients[i]->connfd, s, strlen(s));
  106. }
  107. }
  108. }
  109. }
  110.  
  111. /* Send list of active clients */
  112. void send_active_clients(int connfd){
  113. int i;
  114. char s[64];
  115. for(i=0;i<MAX_CLIENTS;i++){
  116. if(clients[i]){
  117. sprintf(s, "<<CLIENT %d | %s\r\n", clients[i]->uid, clients[i]->name);
  118. send_message_self(s, connfd);
  119. }
  120. }
  121. }
  122.  
  123. /* Strip CRLF */
  124. void strip_newline(char *s){
  125. while(*s != '\0'){
  126. if(*s == '\r' || *s == '\n'){
  127. *s = '\0';
  128. }
  129. s++;
  130. }
  131. }
  132.  
  133. /* Print ip address */
  134. void print_client_addr(struct sockaddr_in addr){
  135. printf("%d.%d.%d.%d",
  136. addr.sin_addr.s_addr & 0xFF,
  137. (addr.sin_addr.s_addr & 0xFF00)>>8,
  138. (addr.sin_addr.s_addr & 0xFF0000)>>16,
  139. (addr.sin_addr.s_addr & 0xFF000000)>>24);
  140. }
  141.  
  142. /* Handle all communication with the client */
  143. void *handle_client(void *arg){
  144. char buff_out[1024];
  145. char buff_in[1024];
  146. int rlen;
  147.  
  148. cli_count++;
  149. client_t *cli = (client_t *)arg;
  150.  
  151. printf("<<ACCEPT ");
  152. print_client_addr(cli->addr);
  153. printf(" REFERENCED BY %d\n", cli->uid);
  154.  
  155. sprintf(buff_out, "<<JOIN, HELLO %s\r\n", cli->name);
  156. send_message_all(buff_out);
  157.  
  158. /* Receive input from client */
  159. while((rlen = read(cli->connfd, buff_in, sizeof(buff_in)-1)) > 0){
  160. buff_in[rlen] = '\0';
  161. buff_out[0] = '\0';
  162. strip_newline(buff_in);
  163.  
  164. /* Ignore empty buffer */
  165. if(!strlen(buff_in)){
  166. continue;
  167. }
  168.  
  169. /* Special options */
  170. if(buff_in[0] == '\\'){
  171. char *command, *param, *username, *password;
  172. command = strtok(buff_in," ");
  173. if(!strcmp(command, "\\QUIT")){
  174. break;
  175. }else if(!strcmp(command, "\\LOGIN")){
  176. username = strtok(NULL, " ");
  177. password = strtok(NULL, " ");
  178. if(username&&password){
  179. if(checkLogin(username,password)){
  180. cli->login=1;
  181. strcpy(cli->name,username);
  182. sprintf(buff_out, "<<%s loged in \r\n", cli->name);
  183. send_message_all(buff_out);
  184. }else{
  185. send_message_self("<<WRONG USERNAME/PASSWORD\r\n", cli->connfd);
  186. }
  187. }else{
  188. send_message_self("<<WRONG USERNAME/PASSWORD\r\n", cli->connfd);
  189. }
  190. }else if(!strcmp(command, "\\PING")){
  191. send_message_self("<<PONG\r\n", cli->connfd);
  192. }else if(!strcmp(command, "\\ACTIVE")){
  193. sprintf(buff_out, "<<CLIENTS %d\r\n", cli_count);
  194. send_message_self(buff_out, cli->connfd);
  195. send_active_clients(cli->connfd);
  196. }else if(!strcmp(command, "\\HELP")){
  197. strcat(buff_out, "\\QUIT Quit chatroom\r\n");
  198. strcat(buff_out, "\\PING Server test\r\n");
  199. strcat(buff_out, "\\NAME <name> Change nickname\r\n");
  200. strcat(buff_out, "\\PRIVATE <reference> <message> Send private message\r\n");
  201. strcat(buff_out, "\\ACTIVE Show active clients\r\n");
  202. strcat(buff_out, "\\HELP Show help\r\n");
  203. send_message_self(buff_out, cli->connfd);
  204. }else{
  205. send_message_self("<<UNKOWN COMMAND\r\n", cli->connfd);
  206. }
  207. }else{
  208. if(cli->login)
  209. {
  210. /* Send message */
  211. sprintf(buff_out, "[%s] %s\r\n", cli->name, buff_in);
  212. send_message(buff_out, cli->uid);
  213. }
  214. else{
  215. sprintf(buff_out, "PLEASE LOG IN\r\n");
  216. send_message_self(buff_out, cli->connfd);
  217. }
  218. }
  219. }
  220.  
  221. /* Close connection */
  222. close(cli->connfd);
  223. sprintf(buff_out, "<<LEAVE, BYE %s\r\n", cli->name);
  224. send_message_all(buff_out);
  225.  
  226. /* Delete client from queue and yeild thread */
  227. queue_delete(cli->uid);
  228. printf("<<LEAVE ");
  229. print_client_addr(cli->addr);
  230. printf(" REFERENCED BY %d\n", cli->uid);
  231. free(cli);
  232. cli_count--;
  233. pthread_detach(pthread_self());
  234.  
  235. return NULL;
  236. }
  237.  
  238. int main(int argc, char *argv[]){
  239. int listenfd = 0, connfd = 0;
  240. struct sockaddr_in serv_addr;
  241. struct sockaddr_in cli_addr;
  242. pthread_t tid;
  243.  
  244. /* Socket settings */
  245. listenfd = socket(AF_INET, SOCK_STREAM, 0);
  246. serv_addr.sin_family = AF_INET;
  247. serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  248. serv_addr.sin_port = htons(5000);
  249.  
  250. /* Bind */
  251. if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0){
  252. perror("Socket binding failed");
  253. return 1;
  254. }
  255.  
  256. /* Listen */
  257. if(listen(listenfd, 10) < 0){
  258. perror("Socket listening failed");
  259. return 1;
  260. }
  261.  
  262. printf("<[SERVER STARTED]>\n");
  263.  
  264. /* Accept clients */
  265. while(1){
  266. socklen_t clilen = sizeof(cli_addr);
  267. connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &clilen);
  268.  
  269. /* Check if max clients is reached */
  270. if((cli_count+1) == MAX_CLIENTS){
  271. printf("<<MAX CLIENTS REACHED\n");
  272. printf("<<REJECT ");
  273. print_client_addr(cli_addr);
  274. printf("\n");
  275. close(connfd);
  276. continue;
  277. }
  278.  
  279. /* Client settings */
  280. client_t *cli = (client_t *)malloc(sizeof(client_t));
  281. cli->addr = cli_addr;
  282. cli->connfd = connfd;
  283. cli->uid = uid++;
  284. sprintf(cli->name, "%d", cli->uid);
  285.  
  286. /* Add client to the queue and fork thread */
  287. queue_add(cli);
  288. pthread_create(&tid, NULL, &handle_client, (void*)cli);
  289.  
  290. /* Reduce CPU usage */
  291. sleep(1);
  292. }
  293. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement