-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.cpp
152 lines (121 loc) · 2.77 KB
/
server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <tchar.h>
#include <thread>
#include <vector>
#define PORT 12345
using namespace std;
#pragma comment(lib, "ws2_32.lib")
bool Initialize()
{
WSADATA data;
return WSAStartup(MAKEWORD(2, 2), &data) == 0;
}
void funcInteractClient(SOCKET clientSocket, vector<SOCKET> &clients)
{
// send /receive client
char buffer[4096];
while (1)
{
// receive incoming data of client in buffer
int byteRecv = recv(clientSocket, buffer, sizeof(buffer), 0);
if (byteRecv <= 0)
{
cout << "Client disconnected" << endl;
break;
}
string message(buffer, byteRecv);
cout << "Message from client :" << message << endl;
// send message to all connected clients excluding itself
for (auto client : clients)
{
if (client != clientSocket)
send(client, message.c_str(), message.length(), 0);
}
}
auto it = find(clients.begin(), clients.end(), clientSocket);
if (it != clients.end())
{
clients.erase(it);
}
closesocket(clientSocket);
}
struct sockaddr_in srv;
int main()
{
int nRet = 0;
// Initialize WSA variable to support env for socket programming
if (!Initialize())
{
cout << "socket initialization failed" << endl;
return 1;
}
else
{
cout << "Socket opened successfull" << endl;
}
// Initialize socket
SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket == INVALID_SOCKET)
{
cout << "Socket connection failed !" << endl;
WSACleanup();
exit(EXIT_FAILURE);
}
else
{
cout << listenSocket << endl;
}
// setup address structure
srv.sin_family = AF_INET;
srv.sin_port = htons(PORT); // convert to network byte order
srv.sin_addr.s_addr = INADDR_ANY;
memset(&(srv.sin_zero), 0, 8);
// bind socket to local port
nRet = bind(listenSocket, (sockaddr *)&srv, sizeof(sockaddr));
if (nRet < 0)
{
cout << "Failed to bind to local port" << endl;
WSACleanup();
exit(EXIT_FAILURE);
}
else
{
cout << "Success bind to local port" << endl;
}
// listen the request from client
nRet = listen(listenSocket, SOMAXCONN);
if (nRet < 0)
{
cout << "Failed to start listen to local port: " << PORT << endl;
WSACleanup();
exit(EXIT_FAILURE);
}
else
{
cout << "Success to listen local port: " << PORT << endl;
}
vector<SOCKET> clients;
// accept client connection
while (1)
{
SOCKET clientSocket = accept(listenSocket, nullptr, nullptr);
if (clientSocket == INVALID_SOCKET)
{
cout << "Invalid client socket" << endl;
}
else
{
cout << "Client connected" << endl;
}
clients.push_back(clientSocket);
// create new seperate thread for handling seperate client
thread t1(funcInteractClient, clientSocket, std::ref(clients));
t1.detach();
}
closesocket(listenSocket);
WSACleanup();
cout << "Server running" << endl;
return 0;
}