Browse Source

update server.hpp & server.cpp, added client class...

Ray-works 1 year ago
parent
commit
19031d94e9
9 changed files with 331 additions and 65 deletions
  1. 2 1
      .gitignore
  2. 35 1
      .vscode/settings.json
  3. 121 0
      client.cpp
  4. 59 0
      client.hpp
  5. 0 1
      main.cpp
  6. BIN
      server
  7. 96 59
      server.cpp
  8. BIN
      server.exe
  9. 18 3
      server.hpp

+ 2 - 1
.gitignore

@@ -1 +1,2 @@
1
-.autogit
1
+.autogit
2
+.vscode

+ 35 - 1
.vscode/settings.json

@@ -4,6 +4,40 @@
4 4
         "iostream": "cpp",
5 5
         "ostream": "cpp",
6 6
         "xstring": "cpp",
7
-        "xlocale": "cpp"
7
+        "xlocale": "cpp",
8
+        "xmemory": "cpp",
9
+        "cctype": "cpp",
10
+        "cmath": "cpp",
11
+        "concepts": "cpp",
12
+        "cstddef": "cpp",
13
+        "cstdint": "cpp",
14
+        "cstdio": "cpp",
15
+        "cstdlib": "cpp",
16
+        "cstring": "cpp",
17
+        "cwchar": "cpp",
18
+        "exception": "cpp",
19
+        "initializer_list": "cpp",
20
+        "ios": "cpp",
21
+        "iosfwd": "cpp",
22
+        "istream": "cpp",
23
+        "limits": "cpp",
24
+        "memory": "cpp",
25
+        "new": "cpp",
26
+        "stdexcept": "cpp",
27
+        "streambuf": "cpp",
28
+        "system_error": "cpp",
29
+        "tuple": "cpp",
30
+        "type_traits": "cpp",
31
+        "typeinfo": "cpp",
32
+        "utility": "cpp",
33
+        "xfacet": "cpp",
34
+        "xiosbase": "cpp",
35
+        "xlocinfo": "cpp",
36
+        "xlocnum": "cpp",
37
+        "xstddef": "cpp",
38
+        "xtr1common": "cpp",
39
+        "xutility": "cpp",
40
+        "thread": "cpp",
41
+        "vector": "cpp"
8 42
     }
9 43
 }

+ 121 - 0
client.cpp

@@ -0,0 +1,121 @@
1
+#include "client.hpp"
2
+#include "server.hpp"
3
+const SOCKET &Client::getSocket() const{
4
+    return this->socket;
5
+}
6
+void Client::setSocket(SOCKET const &socket){
7
+    this->socket = socket;
8
+}
9
+
10
+const sockaddr_in &Client::getSocketInfo(){
11
+    return this->socketInfo;
12
+}
13
+
14
+const string &Client::getName() const{
15
+    return this->name;
16
+}
17
+
18
+void Client::setName(string const &name){
19
+    this->name = name;    
20
+}
21
+
22
+const string &Client::getIP() const{
23
+    return this->ip;
24
+}
25
+
26
+void Client::setIP(string const &ip){
27
+    this->ip = ip;
28
+}
29
+
30
+const u_short &Client::getPort() const{
31
+    return this->port;
32
+}
33
+
34
+void Client::setPort(int const &port){
35
+    this->port = htons(port);
36
+}
37
+
38
+thread *Client::getWorkThread(){
39
+    return this->workThread;
40
+}
41
+
42
+void Client::setWorkThread(thread *workThread){
43
+    this->workThread = workThread;
44
+}
45
+
46
+Client::Client(): Client(0){}
47
+
48
+Client::Client(SOCKET const &socket){
49
+    this->setSocket(socket);
50
+    this->setName("Unknown");
51
+    this->setIP("0.0.0.0");
52
+    this->setPort(0);
53
+}
54
+
55
+Client::~Client(){
56
+    closesocket(this->getSocket());
57
+    this->getWorkThread()->join();
58
+    delete this->getWorkThread();
59
+}
60
+
61
+Client::operator string(){
62
+    return this->getIP() + " (" + to_string(this->getPort()) + ")";
63
+}
64
+
65
+void Client::startWorkingThread(Server *server){
66
+    char *clientIpAddress = inet_ntoa(this->getSocketInfo().sin_addr);
67
+    int clientPort = ntohs(this->getSocketInfo().sin_port); 
68
+
69
+    if(strcmp("0", clientIpAddress) == 0 || clientPort == 0){
70
+        cout << "No valid this ip address and/or port! Disconnecting..." << endl;
71
+        closesocket(this->getSocket());
72
+        return;
73
+    }
74
+
75
+    this->setIP(clientIpAddress);
76
+    this->setPort(clientPort);
77
+
78
+    cout << "[New Connection] " << clientIpAddress << " (" << clientPort << ")" << endl;
79
+
80
+    char msgBuffer[MSG_BUFFER_SIZE];
81
+
82
+    int result = 0;
83
+    do {
84
+        memset(msgBuffer, 0, MSG_BUFFER_SIZE);
85
+
86
+        int result = recv(this->getSocket(), msgBuffer, MSG_BUFFER_SIZE, 0);
87
+        if (result > 0) {
88
+
89
+            cout << msgBuffer << endl;
90
+
91
+            int sendResult = send(this->getSocket(), msgBuffer, result, 0 );
92
+            if (sendResult == SOCKET_ERROR) {
93
+                cout << "send() Error: " << WSAGetLastError() << endl;
94
+                closesocket(this->getSocket());
95
+                this->setSocket(SOCKET_ERROR);
96
+                break;
97
+            }
98
+        } else  {
99
+            switch(WSAGetLastError()){
100
+                case WSAECONNRESET: {
101
+                    cout << "Connection reset by peer." << endl; break;
102
+                }
103
+                case WSAECONNABORTED: {
104
+                    cout << "Software caused connection abort." << endl; break;
105
+                }
106
+                case WSAESHUTDOWN: {
107
+                    cout << "The client socket has been shut down." << endl; break;
108
+                }
109
+                case WSAETIMEDOUT: {
110
+                    cout << "The connection has been dropped because of a network failure or because the peer system failed to respond." << endl; break;
111
+                }
112
+            }
113
+
114
+            closesocket(this->getSocket());
115
+            this->setSocket(SOCKET_ERROR);
116
+        }
117
+
118
+    } while (this->getSocket() != INVALID_SOCKET && this->getSocket() != SOCKET_ERROR);
119
+
120
+    closesocket(this->getSocket());
121
+}

+ 59 - 0
client.hpp

@@ -0,0 +1,59 @@
1
+#ifndef __CLIENT__HPP__
2
+#define __CLIENT__HPP__
3
+
4
+#include <winsock2.h>
5
+#include <string>
6
+#include <ostream>
7
+#include <Ws2tcpip.h>
8
+#include <iostream>
9
+#include <thread>
10
+#define MSG_BUFFER_SIZE 1024
11
+using namespace std;
12
+
13
+class Server;
14
+
15
+class Client {
16
+    private:
17
+        SOCKET socket;
18
+        sockaddr_in socketInfo;
19
+        string name;
20
+        string ip;
21
+        u_short port;
22
+        thread *workThread;
23
+
24
+    public:
25
+        const SOCKET &getSocket() const;
26
+        void setSocket(SOCKET const &socket);
27
+
28
+        const sockaddr_in &getSocketInfo();
29
+
30
+        const string &getName() const;
31
+        void setName(string const &name);
32
+
33
+        const string &getIP() const;
34
+        void setIP(string const &ip);
35
+
36
+        const u_short &getPort() const;
37
+        void setPort(int const &port);
38
+
39
+        thread *getWorkThread();
40
+        void setWorkThread(thread *workThread);
41
+
42
+        Client();
43
+        Client(const Client&) = delete;
44
+        Client(Client&&) = delete;
45
+        Client(SOCKET const &socket);
46
+        ~Client();
47
+
48
+        operator string();
49
+        const Client &operator=(const Client&) = delete;
50
+        const Client &operator=(Client&&) = delete;
51
+
52
+        void startWorkingThread(Server *server);
53
+};
54
+
55
+inline ostream &operator<<(ostream &os, Client &client){
56
+    return (os << static_cast<string>(client));
57
+}
58
+
59
+#endif

+ 0 - 1
main.cpp

@@ -9,6 +9,5 @@ int main(int argc, char** argv){
9 9
 
10 10
     s->start();
11 11
     
12
-    //s->stop();
13 12
     return 0;
14 13
 }

BIN
server


+ 96 - 59
server.cpp

@@ -1,5 +1,5 @@
1 1
 #include "server.hpp"
2
-
2
+#include "client.hpp"
3 3
 double const &Server::getVersion() const {
4 4
     return this->version;
5 5
 }
@@ -48,6 +48,13 @@ void Server::setListenSocket(SOCKET const &listenSocket){
48 48
     this->listenSocket = listenSocket;
49 49
 }
50 50
 
51
+vector<Client *> &Server::getClients(){
52
+    return this->clients;
53
+}
54
+void Server::setClients(vector<Client *> const clients){
55
+    this->clients = clients;
56
+}
57
+
51 58
 SOCKADDR_IN &Server::getServerAddr(){
52 59
     return this->serverAddr;
53 60
 }
@@ -67,9 +74,7 @@ Server::Server(string const &name, double const &version, string const &ip, int
67 74
 }
68 75
 
69 76
 Server::~Server(){
70
-    if (!WSACleanup() == 0) {
71
-        cout << "WSACleanup failed!" << endl;
72
-    }
77
+    this->stop();
73 78
 }
74 79
 
75 80
 Server::operator string(){
@@ -77,6 +82,7 @@ Server::operator string(){
77 82
 }
78 83
 
79 84
 void Server::start(){
85
+    cout << "Server is starting..." << endl;
80 86
     if(WSAStartup(MAKEWORD(2,2),(LPWSADATA)&(this->getWSAData())) != 0){
81 87
         cout << "WSAStartup() Error: " << WSAGetLastError() << endl;
82 88
         exit(1);
@@ -92,79 +98,110 @@ void Server::start(){
92 98
     if(this->getListenSocket() == INVALID_SOCKET) {
93 99
         cout << "listenSocket Error: " << WSAGetLastError()  << endl;
94 100
         WSACleanup();
95
-        exit(1);
101
+        exit(EXIT_FAILURE);
96 102
     }
97 103
 
104
+    cout << "Listen socket created..." << endl;
105
+
98 106
     if(bind(this->getListenSocket(),(SOCKADDR*)&(this->getServerAddr()),sizeof(SOCKADDR_IN)) == SOCKET_ERROR){
99 107
         cout << "bind() Error: " << WSAGetLastError()  << endl;
100 108
         WSACleanup();
101
-        exit(1);
109
+        exit(EXIT_FAILURE);
102 110
     }
103 111
 
112
+    cout << "IP & Port binded..." << endl;
113
+
104 114
     if(listen(this->getListenSocket(), this->getMaxQueue()) == SOCKET_ERROR){
105 115
         cout << "listen() Error: " << WSAGetLastError()  << endl;
106 116
         WSACleanup();
107
-        exit(1);
117
+        exit(EXIT_FAILURE);
108 118
     }
109 119
 
110
-    SOCKET client = accept(listenSocket, NULL, NULL);
111
-    if(client == INVALID_SOCKET){
112
-        cout << "accept: " << WSAGetLastError() << endl;
113
-        exit(1);
114
-    }
120
+    cout << "Server started and listen now!" << endl;
121
+    cout << "Waiting for client..." << endl;
115 122
 
116
-    char recvbuf[4096] = {0};
117
-    int recvbuflen = 4096;
118
-    // Receive until the peer shuts down the connection
119
-    int result = 0;
120
-    do {
121
-
122
-        int result = recv(client, recvbuf, recvbuflen, 0);
123
-        if (result > 0) {
124
-            // printf("Bytes received: %d\n", result);
125
-            cout << "Message: " << recvbuf << endl;
126
-
127
-        // Echo the buffer back to the sender
128
-            int sendResult = send(client, recvbuf, result, 0 );
129
-            if (sendResult == SOCKET_ERROR) {
130
-                printf("send failed with error: %d\n", WSAGetLastError());
131
-                closesocket(client);
132
-                client = SOCKET_ERROR;
133
-                WSACleanup();
134
-                break;
135
-            }
136
-            // printf("Bytes sent: %d\n", sendResult);
137
-
138
-            memset(&recvbuf[0], 0, sizeof(recvbuf));
139
-        }
140
-        else if (result == 0){
141
-            printf("Connection closing...\n");
142
-            client = INVALID_SOCKET;
143
-        } else  {
144
-            // printf("recv failed with error: %d\n", WSAGetLastError());
145
-            // Disconnect Client by Remote
146
-            if(WSAGetLastError() == WSAECONNRESET){
147
-                cout << "Connection lost to client... cleaning up.";
148
-            }
149
-
150
-            closesocket(client);
151
-            client = SOCKET_ERROR;
152
-            WSACleanup();
153
-        }
123
+    for(;;){
124
+        Client *client = new Client();
125
+        int size = sizeof(client->getSocketInfo());
126
+        
127
+        SOCKET clientSocket = accept(this->getListenSocket(), (sockaddr *)&client->getSocketInfo(), &size);
128
+        cout << "New incoming connection..." << endl;
154 129
 
155
-    } while (client != INVALID_SOCKET && client != SOCKET_ERROR);
130
+        if(clientSocket == INVALID_SOCKET){
131
+            cout << "socket accept() Error: " << WSAGetLastError() << endl;
132
+            continue;
133
+        }
156 134
 
157
-    // Disconnect Client by Server
158
-    // if(shutdown(client, SD_SEND) == SOCKET_ERROR){
159
-    //     printf("shutdown failed with error: %d\n", WSAGetLastError());
160
-    //     closesocket(client);
161
-    //     WSACleanup();
162
-    // }
135
+        cout << "Socket is valid, starting client thread..." << endl;
163 136
 
164
-    // cleanup
165
-    closesocket(client);
137
+        client->setSocket(clientSocket);
138
+        client->setWorkThread(new thread(&Client::startWorkingThread, client, this));
139
+    }
166 140
 }
167 141
 
142
+// void Server::clientThread(Client *client){
143
+//     char *clientIpAddress = inet_ntoa(client->getSocketInfo().sin_addr);
144
+//     int clientPort = ntohs(client->getSocketInfo().sin_port); 
145
+
146
+//     if(strcmp("0", clientIpAddress) == 0 || clientPort == 0){
147
+//         cout << "No valid client ip address and/or port! Disconnecting..." << endl;
148
+//         closesocket(client->getSocket());
149
+//         return;
150
+//     }
151
+
152
+//     client->setIP(clientIpAddress);
153
+//     client->setPort(clientPort);
154
+
155
+//     cout << "[New Connection] " << clientIpAddress << " (" << clientPort << ")" << endl;
156
+
157
+//     char msgBuffer[MSG_BUFFER_SIZE];
158
+
159
+//     int result = 0;
160
+//     do {
161
+//         memset(msgBuffer, 0, MSG_BUFFER_SIZE);
162
+
163
+//         int result = recv(client->getSocket(), msgBuffer, MSG_BUFFER_SIZE, 0);
164
+//         if (result > 0) {
165
+
166
+//             cout << msgBuffer << endl;
167
+
168
+//             int sendResult = send(client->getSocket(), msgBuffer, result, 0 );
169
+//             if (sendResult == SOCKET_ERROR) {
170
+//                 cout << "send() Error: " << WSAGetLastError() << endl;
171
+//                 closesocket(client->getSocket());
172
+//                 client->setSocket(SOCKET_ERROR);
173
+//                 break;
174
+//             }
175
+//         } else  {
176
+//             switch(WSAGetLastError()){
177
+//                 case WSAECONNRESET: {
178
+//                     cout << "Connection reset by peer." << endl; break;
179
+//                 }
180
+//                 case WSAECONNABORTED: {
181
+//                     cout << "Software caused connection abort." << endl; break;
182
+//                 }
183
+//                 case WSAESHUTDOWN: {
184
+//                     cout << "The client socket has been shut down." << endl; break;
185
+//                 }
186
+//                 case WSAETIMEDOUT: {
187
+//                     cout << "The connection has been dropped because of a network failure or because the peer system failed to respond." << endl; break;
188
+//                 }
189
+//             }
190
+
191
+//             closesocket(client->getSocket());
192
+//             client->setSocket(SOCKET_ERROR);
193
+//         }
194
+
195
+//     } while (client->getSocket() != INVALID_SOCKET && client->getSocket() != SOCKET_ERROR);
196
+
197
+//     closesocket(client->getSocket());
198
+// }
199
+
168 200
 void Server::stop(){
201
+    for(auto it = this->getClients().begin(); it != this->getClients().end(); it++){
202
+        delete *it;
203
+    }
204
+
205
+    closesocket(this->getListenSocket());
169 206
     WSACleanup();
170 207
 }

BIN
server.exe


+ 18 - 3
server.hpp

@@ -1,12 +1,18 @@
1
-#pragma once
2
-#include <windows.h>
1
+#ifndef __SERVER__HPP__
2
+#define __SERVER__HPP__
3
+
3 4
 #include <winsock2.h>
4 5
 #include <string>
5 6
 #include <ostream>
6 7
 #include <Ws2tcpip.h>
7 8
 #include <iostream>
9
+#include <thread>
10
+#include <vector>
11
+
8 12
 using namespace std;
9 13
 
14
+class Client;
15
+
10 16
 class Server {
11 17
     private:
12 18
         double version;
@@ -18,6 +24,10 @@ class Server {
18 24
         SOCKADDR_IN serverAddr;
19 25
         WSADATA wsaData;
20 26
 
27
+        vector<Client *> clients;
28
+
29
+        void clientThread(Client *client);
30
+
21 31
     public:
22 32
         double const &getVersion() const;
23 33
         void setVersion(double const &version);
@@ -37,6 +47,9 @@ class Server {
37 47
         SOCKET &getListenSocket();
38 48
         void setListenSocket(SOCKET const &listenSocket);
39 49
 
50
+        vector<Client *> &getClients();
51
+        void setClients(vector<Client *> const clients);
52
+
40 53
         SOCKADDR_IN &getServerAddr();
41 54
         WSADATA &getWSAData();
42 55
 
@@ -52,4 +65,6 @@ class Server {
52 65
 
53 66
 inline ostream &operator<<(ostream &os, Server &s){
54 67
     return (os << static_cast<string>(s));
55
-}
68
+}
69
+
70
+#endif  //!__SERVER__H__