Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct SocketState
- {
- SOCKET id; // Socket handle
- int recv; // Receiving?
- int send; // Sending?
- int sendSubType; // Sending sub-type
- char buffer[128];
- int len;
- }
- #define _CRT_SECURE_NO_WARNINGS
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #include <iostream>
- using namespace std;
- #include <winsock2.h>
- #include <string.h>
- #include <time.h>
- # include <ctime>
- #include <ws2tcpip.h>
- #include <assert.h>
- #pragma comment(lib, "Ws2_32.lib")
- struct SocketState
- {
- SOCKET id; // Socket handle
- int recv; // Receiving?
- int send; // Sending?
- int sendSubType; // Sending sub-type
- char buffer[128];
- int len;
- };
- const int TIME_PORT = 27015;
- const int MAX_SOCKETS = 60;
- const int EMPTY = 0;
- const int LISTEN = 1;
- const int RECEIVE = 2;
- const int IDLE = 3;
- const int SEND = 4;
- const int SEND_TIME = 1;
- const int SEND_SECONDS = 2;
- bool addSocket(SOCKET id, int what);
- void removeSocket(int index);
- void acceptConnection(int index);
- void receiveMessage(int index);
- void sendMessage(int index);
- struct SocketState sockets[MAX_SOCKETS] = { 0 };
- int socketsCount = 0;
- void main()
- {
- WSAData wsaData;
- if (NO_ERROR != WSAStartup(MAKEWORD(2, 2), &wsaData))
- {
- cout << "Time Server: Error at WSAStartup()n";
- return;
- }
- SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (INVALID_SOCKET == listenSocket)
- {
- cout << "Time Server: Error at socket(): " << WSAGetLastError() << endl;
- WSACleanup();
- return;
- }
- sockaddr_in serverService;
- serverService.sin_family = AF_INET;
- serverService.sin_addr.s_addr = INADDR_ANY;
- serverService.sin_port = htons(TIME_PORT);
- if (SOCKET_ERROR == bind(listenSocket, (SOCKADDR*)& serverService, sizeof(serverService)))
- {
- cout << "Time Server: Error at bind(): " << WSAGetLastError() << endl;
- closesocket(listenSocket);
- WSACleanup();
- return;
- }
- if (SOCKET_ERROR == listen(listenSocket, 5))
- {
- cout << "Time Server: Error at listen(): " << WSAGetLastError() << endl;
- closesocket(listenSocket);
- WSACleanup();
- return;
- }
- addSocket(listenSocket, LISTEN);
- while (true)
- {
- fd_set waitRecv;
- FD_ZERO(&waitRecv);
- for (int i = 0; i < MAX_SOCKETS; i++)
- {
- if ((sockets[i].recv == LISTEN) || (sockets[i].recv == RECEIVE))
- FD_SET(sockets[i].id, &waitRecv);
- }
- fd_set waitSend;
- FD_ZERO(&waitSend);
- for (int i = 0; i < MAX_SOCKETS; i++)
- {
- if (sockets[i].send == SEND)
- FD_SET(sockets[i].id, &waitSend);
- }
- struct timeval timeout;
- timeout.tv_sec = 15;
- timeout.tv_usec = 0;
- int nfd = select(0, &waitRecv, &waitSend, NULL, NULL);
- if (nfd == SOCKET_ERROR)
- {
- cout << "Time Server: Error at select(): " << WSAGetLastError() << endl;
- WSACleanup();
- return;
- }
- for (int i = 0; i < MAX_SOCKETS && nfd > 0; i++)
- {
- if (FD_ISSET(sockets[i].id, &waitRecv))
- {
- nfd--;
- switch (sockets[i].recv)
- {
- case LISTEN:
- acceptConnection(i);
- break;
- case RECEIVE:
- receiveMessage(i);
- break;
- }
- }
- }
- for (int i = 0; i < MAX_SOCKETS && nfd > 0; i++)
- {
- if (FD_ISSET(sockets[i].id, &waitSend))
- {
- nfd--;
- switch (sockets[i].send)
- {
- case SEND:
- sendMessage(i);
- break;
- }
- }
- }
- }
- // Closing connections and Winsock.
- cout << "Time Server: Closing Connection.n";
- closesocket(listenSocket);
- WSACleanup();
- }
- bool addSocket(SOCKET id, int what)
- {
- for (int i = 0; i < MAX_SOCKETS; i++)
- {
- if (sockets[i].recv == EMPTY)
- {
- sockets[i].id = id;
- sockets[i].recv = what;
- sockets[i].send = IDLE;
- sockets[i].len = 0;
- socketsCount++;
- return (true);
- }
- }
- return (false);
- }
- void removeSocket(int index)
- {
- sockets[index].recv = EMPTY;
- sockets[index].send = EMPTY;
- socketsCount--;
- }
- void acceptConnection(int index)
- {
- SOCKET id = sockets[index].id;
- struct sockaddr_in from; // Address of sending partner
- int fromLen = sizeof(from);
- SOCKET msgSocket = accept(id, (struct sockaddr*) & from, &fromLen);
- if (INVALID_SOCKET == msgSocket)
- {
- cout << "Time Server: Error at accept(): " << WSAGetLastError() << endl;
- return;
- }
- cout << "Time Server: Client " << inet_ntoa(from.sin_addr) << ":" << ntohs(from.sin_port) << " is connected." << endl;
- //
- // Set the socket to be in non-blocking mode.
- //
- unsigned long flag = 1;
- if (ioctlsocket(msgSocket, FIONBIO, &flag) != 0)
- {
- cout << "Time Server: Error at ioctlsocket(): " << WSAGetLastError() << endl;
- }
- if (addSocket(msgSocket, RECEIVE) == false)
- {
- cout << "ttToo many connections, dropped!n";
- closesocket(id);
- }
- return;
- }
- void receiveMessage(int index)
- {
- SOCKET msgSocket = sockets[index].id;
- int len = sockets[index].len;
- int bytesRecv = recv(msgSocket, &sockets[index].buffer[len], sizeof(sockets[index].buffer) - len, 0);
- if (SOCKET_ERROR == bytesRecv)
- {
- cout << "Time Server: Error at recv(): " << WSAGetLastError() << endl;
- closesocket(msgSocket);
- removeSocket(index);
- return;
- }
- if (bytesRecv == 0)
- {
- closesocket(msgSocket);
- removeSocket(index);
- return;
- }
- else
- {
- sockets[index].buffer[len + bytesRecv] = '