Advertisement
tuanln

TCPChatServer

Nov 18th, 2015
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.23 KB | None | 0 0
  1. // TCPChatServer.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "stdio.h"
  6. #include "conio.h"
  7. #include "winsock2.h"
  8. #include "ws2tcpip.h"
  9.  
  10. struct packet
  11. {
  12.     BYTE head;
  13.     WORD length;
  14.     BYTE data[4096];
  15. };
  16.  
  17. struct user
  18. {
  19.     char nickname[32];
  20.     char password[32];
  21.     bool isOnline;
  22. };
  23.  
  24. struct ClientInfo
  25. {
  26.     SOCKET c;
  27.     SOCKADDR_IN cAddr;
  28.     char nickname[32];
  29.     char password[32];
  30.     char filename[256];
  31.     bool state = false;
  32.     bool nhanfile = false;
  33.     bool dongynhan = false;
  34. };
  35.  
  36. SOCKET s;
  37. SOCKADDR_IN sAddr;
  38. user * users[5];
  39. ClientInfo * cClient[1024];
  40.  
  41. int nClient = 0;
  42.  
  43. DWORD WINAPI ClientThread(LPVOID Param) {
  44.     int i = (int)Param, j, k;
  45.     int len;
  46.     char buf[1024], msg[1024], filename[256];
  47.     int filesize, byterecv;
  48.     char ans;
  49.     double current = 0.0;
  50.     FILE* fp = NULL;
  51.     packet pk_recv, pk_send;
  52.  
  53.     char* error = "[Error]Unknown command!\n";
  54.     char* login = "Server: Login to Server\n";
  55.     pk_send.head = 0;
  56.     pk_send.length = strlen(login);
  57.     memcpy(pk_send.data, login, pk_send.length);
  58.     send(cClient[i]->c, (char*)&pk_send, sizeof(struct packet), 0);
  59.  
  60.     while (true) {
  61.         len = recv(cClient[i]->c, (char*)&pk_recv, sizeof(struct packet), MSG_WAITALL);
  62.         if (len < pk_recv.length) break;
  63.  
  64.         if (cClient[i]->dongynhan == true) {
  65.             //cClient[i]->nhanfile = true;
  66.             fp = fopen(filename, "wb");
  67.             byterecv = 0;
  68.             cClient[i]->dongynhan = false;
  69.         }
  70.  
  71.         if (pk_recv.head == 0) {
  72.             pk_recv.data[pk_recv.length-1] = 0;
  73.             if (strnicmp((char*)pk_recv.data, "login ", 6) == 0) {
  74.                 char nickname[32], password[32];
  75.                 bool isNoError = false;
  76.                 char * pos = NULL;
  77.                 pos = strchr((char*)pk_recv.data + 6, ' ');
  78.                 if (pos != 0) {
  79.                     strncpy(nickname, (char*)pk_recv.data + 6, pos - (char*)pk_recv.data - 6);
  80.                     nickname[pos - (char*)pk_recv.data - 6] = 0;
  81.                     sprintf(password, pos+1);
  82.                     for (j = 0; j < 5; j++) {
  83.                         if (strcmp(nickname,users[j]->nickname) == 0
  84.                             && strcmp(password, users[j]->password) == 0
  85.                             && users[j]->isOnline == false) {
  86.                             strcpy(cClient[i]->nickname, nickname);
  87.                             strcpy(cClient[i]->password, password);
  88.                             cClient[i]->state = true;
  89.                             users[j]->isOnline = true;
  90.                             sprintf(msg, "[Info] %s logged in!\n", cClient[i]->nickname);
  91.                             printf(msg);
  92.                             for (k = 0; k < nClient; k++)
  93.                                 if (cClient[k] != 0 && cClient[k]->state == true) {
  94.                                     pk_send.head = 0;
  95.                                     pk_send.length = strlen(msg);
  96.                                     memcpy(pk_send.data, msg, pk_send.length);
  97.                                     send(cClient[k]->c, (char*)&pk_send, sizeof(struct packet), 0);
  98.                                 };
  99.                             isNoError = true;
  100.                             break;
  101.                         }
  102.                     }
  103.                     if (isNoError == false) {
  104.                         sprintf(msg, "[Error] Login error!\n");
  105.                         pk_send.head = 0;
  106.                         pk_send.length = strlen(msg);
  107.                         memcpy(pk_send.data, msg, pk_send.length);
  108.                         send(cClient[i]->c, (char*)&pk_send, sizeof(struct packet), 0);
  109.                     }
  110.                 }
  111.                 continue;
  112.             }
  113.             if (strnicmp((char*)pk_recv.data, "list", 4) == 0) {
  114.                 if (cClient[i]->state == false) continue;
  115.                 sprintf(msg, "----------------------\n[Info] User is online:\n");
  116.                 for (j = 0; j < nClient; j++) {
  117.                     if (cClient[j]->state == true) sprintf(msg, "%s%s\n", msg, cClient[j]->nickname);
  118.                 }
  119.                 sprintf(msg, "%s----------------------\n", msg);
  120.                 pk_send.head = 0;
  121.                 pk_send.length = strlen(msg);
  122.                 memcpy(pk_send.data, msg, pk_send.length);
  123.                 send(cClient[i]->c, (char*)&pk_send, sizeof(struct packet), 0);
  124.                 continue;
  125.             }
  126.             if (strnicmp((char*)pk_recv.data, "chat * ", 7) == 0) {
  127.                 if (cClient[i]->state == false) continue;
  128.                 sprintf(msg, "[%s] %s\n", cClient[i]->nickname, (char*)pk_recv.data + 7);
  129.                 printf(msg);
  130.                 for (j = 0; j < nClient;j++)
  131.                     if (i != j && cClient[j] != 0 && cClient[j]->state == true) {
  132.                         pk_send.head = 0;
  133.                         pk_send.length = strlen(msg);
  134.                         memcpy(pk_send.data, msg, pk_send.length);
  135.                         send(cClient[j]->c, (char*)&pk_send, sizeof(struct packet), 0);
  136.                     }
  137.                 continue;
  138.             }
  139.             if (strnicmp((char*)pk_recv.data, "chat ", 5) == 0) {
  140.                 if (cClient[i]->state == false) continue;
  141.                 char nickname[32];
  142.                 char* pos = NULL;
  143.                 pos = strchr((char*)pk_recv.data + 5, ' ');
  144.                 if (pos != 0) {
  145.                     strncpy(nickname, (char*)pk_recv.data + 5, pos - (char*)pk_recv.data - 5);
  146.                     nickname[pos - (char*)pk_recv.data - 5] = 0;
  147.                     sprintf(msg, "[%s] %s\n", cClient[i]->nickname, pos + 1);
  148.                     for (j = 0; j < nClient;j++)
  149.                         if (j != i
  150.                             && cClient[j] != 0
  151.                             && cClient[j]->state == true
  152.                             && stricmp(nickname, cClient[j]->nickname) == 0) {
  153.                            
  154.                             pk_send.head = 0;
  155.                             pk_send.length = strlen(msg);
  156.                             memcpy(pk_send.data, msg, pk_send.length);
  157.                             send(cClient[j]->c, (char*)&pk_send, sizeof(struct packet), 0);
  158.                         };
  159.                     if (stricmp(nickname, "server") == 0) printf("[%s] %s\n", cClient[i]->nickname, pos + 1);
  160.                 }
  161.                 continue;
  162.             }
  163.             pk_send.head = 0;
  164.             pk_send.length = strlen(error);
  165.             memcpy(pk_send.data, error, pk_send.length);
  166.             send(cClient[i]->c, (char*)&pk_send, sizeof(struct packet), 0);
  167.             continue;
  168.         }
  169.         if (pk_recv.head == 1) {
  170.             if (cClient[i]->state == false) continue;
  171.             char target[33];
  172.             strncpy(filename, (char*)pk_recv.data, 255);
  173.             filename[255] = 0;
  174.             strncpy(target, (char*)pk_recv.data + 255, 32);
  175.             target[32] = 0;
  176.             memcpy(&filesize, pk_recv.data + 255 + 32, 4);
  177.             if (stricmp(target, "server") == 0) {
  178.                 printf("[%s] muon gui toi [%s] file %s, kich thuoc %d byte. Co nhan khong(Y/N)?\n",
  179.                     cClient[i]->nickname, target, filename, filesize);
  180.                 sprintf(cClient[i]->filename, filename);
  181.                 cClient[i]->nhanfile = true;
  182.             }
  183.             else {
  184.                 pk_send.head = 5;
  185.                 pk_send.length = 255 + 32 + 32 + 4;
  186.                 for (j = 0; j < 5; j++)
  187.                     if (stricmp(target, users[j]->nickname) == 0 && users[j]->isOnline == true) break;
  188.                 send(cClient[j]->c, (char*)&pk_send.head, sizeof(pk_send.head), 0);
  189.                 send(cClient[j]->c, (char*)&pk_send.length, sizeof(pk_send.length), 0);
  190.                 send(cClient[j]->c, filename, 255, 0);
  191.                 send(cClient[j]->c, target, 255, 0);
  192.                 send(cClient[j]->c, (char*)&filesize, sizeof(filesize), 0);
  193.             }
  194.             continue;
  195.         }
  196.         if (pk_recv.head == 4) {
  197.             fwrite(pk_recv.data, 1, pk_recv.length, fp);   
  198.             //Sleep(1);
  199.             byterecv += pk_recv.length;
  200.             current = (double)byterecv / (double)filesize * 100;
  201.             printf("[%s] %0.2f%%\r", cClient[i]->nickname, current);
  202.             if (byterecv == filesize) {
  203.                 printf("Xong!\n");
  204.                 fclose(fp);
  205.             }
  206.             continue;
  207.         }
  208.     }
  209.  
  210.  
  211.     return 0;
  212. }
  213.  
  214. DWORD WINAPI SenderThread(LPVOID Param) {
  215.     char buf[1024], msg[1024];
  216.     int i;
  217.     packet pk_recv, pk_send;
  218.     while (true) {
  219.         for (i = 0; i < nClient; i++) {
  220.             if (cClient[i]->nhanfile == true) {
  221.                 printf("Tra loi nhan file tu [%s]: ", cClient[i]->nickname);
  222.                 fflush(stdin);
  223.                 fgets(buf, 1024, stdin);
  224.                 if (strnicmp(buf, "Y", 1) == 0 && strnicmp(buf, "y", 1) == 0) {
  225.                     pk_send.head = 2;
  226.                     pk_send.length = 255;
  227.                     cClient[i]->nhanfile = false;
  228.                     cClient[i]->dongynhan = true;
  229.                 }
  230.                 else if (strnicmp(buf, "N", 1) == 0 && strnicmp(buf, "n", 1) == 0) {
  231.                     pk_send.head = 3;
  232.                     pk_send.length = 0;
  233.                     cClient[i]->nhanfile = false;
  234.                 }
  235.                 if (pk_send.head == 2)
  236.                     memcpy(pk_send.data, cClient[i]->filename, 255);
  237.                 send(cClient[i]->c, (char*)&pk_send, sizeof(struct packet), 0);
  238.                 continue;
  239.             }
  240.         }
  241.         fflush(stdin);
  242.         fgets(buf, 1024, stdin);
  243.         sprintf(msg, "[Server] %s\n", buf);
  244.         for (i = 0; i < nClient;i++)
  245.             if (cClient[i] != 0 && cClient[i]->state == true) {
  246.                 pk_send.head = 0;
  247.                 pk_send.length = strlen(msg);
  248.                 memcpy(pk_send.data, msg, pk_send.length);
  249.                 send(cClient[i]->c, (char*)&pk_send, sizeof(struct packet), 0);
  250.             }
  251.     }
  252.     return 0;
  253. }
  254.  
  255. int main() {
  256.  
  257.     for (int j = 0; j < 5; j++) {
  258.         users[j] = 0;
  259.         users[j] = new user;
  260.     }
  261.     strcpy(users[0]->nickname, "123"); strcpy(users[0]->password, "123"); users[0]->isOnline = false;
  262.     strcpy(users[1]->nickname, "456"); strcpy(users[1]->password, "456"); users[1]->isOnline = false;
  263.     strcpy(users[2]->nickname, "789"); strcpy(users[2]->password, "789"); users[2]->isOnline = false;
  264.     strcpy(users[3]->nickname, "abc"); strcpy(users[3]->password, "abc"); users[3]->isOnline = false;
  265.     strcpy(users[4]->nickname, "cde"); strcpy(users[4]->password, "cde"); users[4]->isOnline = false;
  266.  
  267.     WSADATA wsadata;
  268.     int ret = WSAStartup(MAKEWORD(2, 2), &wsadata);
  269.  
  270.     s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  271.     sAddr.sin_family = AF_INET;
  272.     sAddr.sin_port = htons(8888);
  273.     sAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  274.  
  275.     ret = bind(s, (sockaddr*)&sAddr, sizeof(sAddr));
  276.     ret = listen(s, 16);
  277.  
  278.     int i, cAddrLen = sizeof(SOCKADDR_IN);
  279.     bool datachluong = false;
  280.     for (i = 0; i < 1024; i++) cClient[i] = 0;
  281.  
  282.     while (true) {
  283.         for (i = 0; i < nClient; i++) if (cClient[i] == 0) break;
  284.         cClient[i] = new ClientInfo;
  285.         cClient[i]->c = accept(s, (sockaddr*)&cClient[i]->cAddr, &cAddrLen);
  286.         CreateThread(0, 0, ClientThread, (LPVOID)i, 0, 0);
  287.         if (datachluong == false) {
  288.             CreateThread(0, 0, SenderThread, 0, 0, 0);
  289.             datachluong = true;
  290.         }
  291.         if (i == nClient) nClient++;
  292.     }
  293.  
  294.     for (i = 0; i < nClient; i++)
  295.         if (cClient[i] != 0) {
  296.             closesocket(cClient[i]->c);
  297.             delete cClient[i];
  298.             cClient[i] = 0;
  299.         };
  300.     WSACleanup();
  301.     getch();
  302.  
  303.     return 0;
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement