// Server part of Server-Client chat. Developed by Mr_Dezz #include #include #include #include #include #pragma comment(lib, "Ws2_32.lib") using namespace std; int main(void) { //Key constants const char IP_SERV[] = "127.0.0.1"; // Enter local Server IP address const int PORT_NUM = 5000; // Enter Open working server port const short BUFF_SIZE = 1024; // Maximum size of buffer for exchange info between server and client // Key variables for all program int erStat; // Keeps socket errors status //IP in string format to numeric format for socket functions. Data is in "ip_to_num" in_addr ip_to_num; erStat = inet_pton(AF_INET, IP_SERV, &ip_to_num); if (erStat <= 0) { cout << "Error in IP translation to special numeric format" << endl; return 1; } // WinSock initialization WSADATA wsData; erStat = WSAStartup(MAKEWORD(2,2), &wsData); if ( erStat != 0 ) { cout << "Error WinSock version initializaion #"; cout << WSAGetLastError(); return 1; } else cout << "WinSock initialization is OK" << endl; // Server socket initialization SOCKET ServSock = socket(AF_INET, SOCK_STREAM, 0); if (ServSock == INVALID_SOCKET) { cout << "Error initialization socket # " << WSAGetLastError() << endl; closesocket(ServSock); WSACleanup(); return 1; } else cout << "Server socket initialization is OK" << endl; // Server socket binding sockaddr_in servInfo; ZeroMemory(&servInfo, sizeof(servInfo)); // Initializing servInfo structure servInfo.sin_family = AF_INET; servInfo.sin_addr = ip_to_num; servInfo.sin_port = htons(PORT_NUM); erStat = bind(ServSock, (sockaddr*)&servInfo, sizeof(servInfo)); if ( erStat != 0 ) { cout << "Error Socket binding to server info. Error # " << WSAGetLastError() << endl; closesocket(ServSock); WSACleanup(); return 1; } else cout << "Binding socket to Server info is OK" << endl; //Starting to listen to any Clients erStat = listen(ServSock, SOMAXCONN); if ( erStat != 0 ) { cout << "Can't start to listen to. Error # " << WSAGetLastError() << endl; closesocket(ServSock); WSACleanup(); return 1; } else { cout << "Listening..." << endl; } //Client socket creation and acception in case of connection sockaddr_in clientInfo; ZeroMemory(&clientInfo, sizeof(clientInfo)); // Initializing clientInfo structure int clientInfo_size = sizeof(clientInfo); SOCKET ClientConn = accept(ServSock, (sockaddr*)&clientInfo, &clientInfo_size); if (ClientConn == INVALID_SOCKET) { cout << "Client detected, but can't connect to a client. Error # " << WSAGetLastError() << endl; closesocket(ServSock); closesocket(ClientConn); WSACleanup(); return 1; } else { cout << "Connection to a client established successfully" << endl; char clientIP[22]; inet_ntop(AF_INET, &clientInfo.sin_addr, clientIP, INET_ADDRSTRLEN); // Convert connected client's IP to standard string format cout << "Client connected with IP address " << clientIP << endl; } //Exchange text data between Server and Client. Disconnection if a client send "xxx" vector servBuff(BUFF_SIZE), clientBuff(BUFF_SIZE); // Creation of buffers for sending and receiving data short packet_size = 0; // The size of sending / receiving packet in bytes while (true) { packet_size = recv(ClientConn, servBuff.data(), servBuff.size(), 0); // Receiving packet from client. Program is waiting (system pause) until receive cout << "Client's message: " << servBuff.data() << endl; cout << "Your (host) message: "; fgets(clientBuff.data(), clientBuff.size(), stdin); // Check whether server would like to stop chatting if (clientBuff[0] == 'x' && clientBuff[1] == 'x' && clientBuff[2] == 'x') { shutdown(ClientConn, SD_BOTH); closesocket(ServSock); closesocket(ClientConn); WSACleanup(); return 0; } packet_size = send(ClientConn, clientBuff.data(), clientBuff.size(), 0); if (packet_size == SOCKET_ERROR) { cout << "Can't send message to Client. Error # " << WSAGetLastError() << endl; closesocket(ServSock); closesocket(ClientConn); WSACleanup(); return 1; } } closesocket(ServSock); closesocket(ClientConn); WSACleanup(); return 0; }