Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC diagnostic ignored "-Wconversion-null"
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #include <WinSock2.h>
- #include <iostream>
- #include <string>
- #define MAX_CONN 100
- SOCKET Connections[MAX_CONN];
- int TotalConnections = 0;
- enum Packet
- {
- P_ChatMessage,
- P_Test
- };
- bool ProcessPacket(int ID, Packet packettype)
- {
- std::string remitent = "From " + std::to_string(ID+1) + ": ";
- int length = remitent.length();
- switch (packettype)
- {
- case P_ChatMessage:
- {
- int bufferlength; //Length of the string
- //Logic for receiving a string
- recv(Connections[ID], (char*)&bufferlength, sizeof(int), NULL); //get buffer length
- char * buffer = new char[bufferlength]; //Allocate buffer
- recv(Connections[ID], buffer, bufferlength, NULL); //get buffer message from client
- std::cout << std::endl << "Recieved Message Packet from ID: " << ID+1 << std::endl;
- for (int i = 0; i < TotalConnections; i++) //For each client connection
- {
- if (i == ID) //Don't send the chat message to the same user who sent it
- continue; //Skip user
- Packet chatmessagepacket = P_ChatMessage; //create chat message packet to be sent
- send(Connections[i], (char*)&chatmessagepacket, sizeof(Packet), NULL); //send chat message packet
- send(Connections[i], (char*)&length, sizeof(int), NULL); //send the length of the remitent message
- send(Connections[i], remitent.c_str(), length, NULL); //send the remitent message
- send(Connections[i], (char*)&bufferlength, sizeof(int), NULL);//send the buffer length to client at index i
- send(Connections[i], buffer, bufferlength, NULL);//send the chat message to client at index i
- std::cout << "Sended Message Packet to ID: " << i+1 << std::endl;
- }
- delete[] buffer; //Deallocate buffer to stop from leaking memory
- break;
- }
- case P_Test:
- std::cout << "Recieved Test Packet from ID: " << ID << std::endl;
- break;
- default:
- std::cout << "Unknown packet received." << std::endl;
- break;
- }
- return true;
- }
- void ClientHandlerThread(int ID) //ID = the index in the SOCKET Connections array
- {
- while (true)
- {
- //First get the packet type
- Packet packettype;
- recv(Connections[ID], (char*)&packettype, sizeof(Packet), NULL); //Receive packet type from client
- //Once we have the packet type, process the packet
- if (!ProcessPacket(ID, packettype)) //If the packet is not properly processed
- break; //break out of our client handler loop
- Sleep(1000);
- }
- closesocket(Connections[ID]); //close the socket that was being used for the client's connection
- std::cout << "Closed connection for ID: " << ID << std::endl;
- }
- int main()
- {
- //Winsock Startup
- WSAData wsaData;
- WORD DllVersion = MAKEWORD(2, 1);
- if (WSAStartup(DllVersion, &wsaData) != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
- {
- MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);
- return 0;
- }
- SOCKADDR_IN addr; //Address that we will bind our listening socket to
- int addrlen = sizeof(addr); //length of the address (required for accept call)
- addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Broadcast locally
- addr.sin_port = htons(1111); //Port
- addr.sin_family = AF_INET; //IPv4 Socket
- SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
- bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); //Bind the address to the socket
- listen(sListen, SOMAXCONN); //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max Connections
- std::cout << "Listening..." << std::endl;
- SOCKET newConnection; //Socket to hold the client's connection
- for (int i = 0; i < MAX_CONN; i++)
- {
- newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen); //Accept a new connection
- if (newConnection == 0) //If accepting the client connection failed
- {
- std::cout << "Failed to accept the client's connection." << std::endl;
- }
- else //If client connection properly accepted
- {
- std::cout << "Client " << TotalConnections+1 << " Connected!" << std::endl;
- Connections[i] = newConnection; //Set socket in array to be the newest connection before creating the thread to handle this client's socket.
- int sendID = TotalConnections + 1;
- send(Connections[i], (char*)&sendID, sizeof(int), NULL);
- CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientHandlerThread, (LPVOID)(i), NULL, NULL); //Create Thread to handle this client. The index in the socket array for this thread is the value (i).
- Packet testpacket = P_Test;
- send(Connections[i], (char*)&testpacket, sizeof(Packet), NULL); //Send test packet
- TotalConnections++; //Incremenent total # of clients that have connected
- }
- Sleep(20);
- }
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement