Dit is de thread code van m'n serverthread. Hij crasht niét als je:
- steeds 1 client connect en disconnect en dat blijft herhalen
- je een eerste client connect en vervolgens een tweede client die je connect en disconnect en dat blijft herhalen (dus 1ste client blijft constant geconnect)
Hij crasht bvb wél als:
- je een eerste client connect, dan een tweede connect, dan de eerste disconnect en dan de tweede disconnect.
Dit is de code van de thread:
Dit is de code van de linked lists:
- steeds 1 client connect en disconnect en dat blijft herhalen
- je een eerste client connect en vervolgens een tweede client die je connect en disconnect en dat blijft herhalen (dus 1ste client blijft constant geconnect)
Hij crasht bvb wél als:
- je een eerste client connect, dan een tweede connect, dan de eerste disconnect en dan de tweede disconnect.
Dit is de code van de thread:
C++:
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
| // A client thread to start when a new client has succesfully connected. static DWORD WINAPI ThreadHandler(void* insocket_) { int nRetval = 0; SOCKET insocket = (SOCKET)insocket_; vector<char> theVector; char *pChar; int result; char acReadBuffer; int nReadBytes; do { nReadBytes = recv(insocket, &acReadBuffer, 1, 0); if (nReadBytes > 0) { switch (acReadBuffer) { case '\n': pChar = new char[theVector.size() + 1]; memset(pChar, 0, theVector.size() + 1); for (int i = 0; i<theVector.size(); i++) pChar[i] = theVector[i]; Cns_Addline("Received %d bytes from client [%s]", theVector.size()+1, pChar); //LL_Sockets_SendAll(pChar); LL_Sockets_SendAllButSelf(pChar, insocket); pChar = ""; theVector.clear(); break; default: theVector.push_back(acReadBuffer); break; } } else if (nReadBytes == SOCKET_ERROR) { Cns_Addline("Handling of packages failed"); nRetval = 3; } } while (nReadBytes != 0); Cns_Addline("Connection closed by peer"); if (theVector.size()>0) theVector.clear(); free(pChar); pChar = NULL; LL_Sockets_Viewlist(); LL_Sockets_Remove(insocket); Cns_Addline("Socket removed from list"); LL_Sockets_Viewlist(); Cns_Addline("Shutting connection down..."); if (ShutdownConnection(insocket)) Cns_Addtolastline("[ok]"); else { Cns_Addtolastline("[error: Connection shutdown failed"); nRetval = 3; } ////////////////////////////// // thread crashes on return // ////////////////////////////// return nRetval; } |
Dit is de code van de linked lists:
C++:
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
| #include "main.h" #include <stdlib.h> struct LL_SOCKETS { SOCKET sock; int id; int score; char* nick; LL_SOCKETS *next; // pointer to next list item }; extern LL_SOCKETS *ll_tex_start; //start pointer LL_SOCKETS *ll_sock_start = NULL; //add an item in the FIFO (first in first out) list int LL_Sockets_Add(SOCKET insocket) { static int idCounter; idCounter++; LL_SOCKETS *new_item = new LL_SOCKETS; // make a new list item new_item->sock = insocket; new_item->id = idCounter; // define the new item new_item->nick = "undefined"; new_item->next = ll_sock_start; // push the list a bit further to the right ll_sock_start = new_item; // set the start pointer to the this item Cns_Addline("[socket added to list]"); return idCounter; } // find an element by its id void LL_Sockets_Get(const int id) { LL_SOCKETS *ll_sock_current = NULL; // current read pointer LL_SOCKETS *ll_sock_previous = NULL; // previous read pointer ll_sock_current = ll_sock_start; while (ll_sock_current) { if (ll_sock_current->id != id) { Cns_Addline("Found: %d", id); return; } ll_sock_current = ll_sock_current->next; // read next socket } } void LL_Sockets_Viewlist() { int count = 0; LL_SOCKETS *ll_sock_current = NULL; // current read pointer ll_sock_current = ll_sock_start; Cns_Addline("Current socket list:"); while (ll_sock_current) { count++; Cns_Addline(" - ID %d, player name '%s'", ll_sock_current->id, ll_sock_current->nick); ll_sock_current = ll_sock_current->next; // read next socket } Cns_Addline(" (%d clients in list)", count); } void LL_Sockets_Remove(SOCKET insock) { LL_SOCKETS *ll_sock_current = NULL; // current read pointer LL_SOCKETS *ll_sock_previous = NULL; // previous read pointer ll_sock_previous = ll_sock_start; ll_sock_current = ll_sock_start->next; if (ll_sock_start->sock == insock) // socket to delete is first socket in list { Cns_Addline("Removed from list: ID %d, player name '%s'", ll_sock_start->id, ll_sock_start->nick); if (ll_sock_current) // there is a second client { // remove the first socket and shift list free(ll_sock_start); ll_sock_start = NULL; ll_sock_start = ll_sock_current; } else { // first (and only) client disconnects // remove the (only) socket free(ll_sock_start); ll_sock_start = NULL; } return; } else { // look further in list while (ll_sock_current) { if (ll_sock_current->sock == insock) { Cns_Addline("Removed from list: ID %d, player name '%s'", ll_sock_current->id, ll_sock_current->nick); ll_sock_previous->next = ll_sock_current->next; free(ll_sock_current); ll_sock_current = NULL; return; } ll_sock_previous = ll_sock_current; // store current socket in 'previous socket' pointer ll_sock_current = ll_sock_current->next; // read next socket } } } void LL_Sockets_SendAll(char* data) { char terminator = '\n'; LL_SOCKETS *ll_sock_current = NULL; // current read pointer ll_sock_current = ll_sock_start; // set current read pointer to first socket in list while (ll_sock_current) { int nTemp = send(ll_sock_current->sock, data, strlen(data), 0); nTemp += send(ll_sock_current->sock, &terminator, 1, 0); if (nTemp > 0) // sent to client { Cns_Addline("Sent %d bytes back to foreign client %d", nTemp, ll_sock_current->id); } else if (nTemp == SOCKET_ERROR) { // client error Cns_Addline("Client error in linked list Sendall()"); } else { // client quit // client closed connection before we could reply to // all the data it sent, so bomb out early. Cns_Addline("Peer unexpectedly dropped connection!" ); } ll_sock_current = ll_sock_current->next; // read next socket } free(data); data = NULL; } void LL_Sockets_SendAllButSelf(char* data, SOCKET insock) { char terminator = '\n'; LL_SOCKETS *ll_sock_current = NULL; // current read pointer ll_sock_current = ll_sock_start; // set current read pointer to first socket in list while (ll_sock_current) { if (ll_sock_current->sock != insock) { int nTemp = send(ll_sock_current->sock, data, strlen(data), 0); nTemp += send(ll_sock_current->sock, &terminator, 1, 0); if (nTemp > 0) // sent to client { Cns_Addline("Sent %d bytes back to foreign client %d", nTemp, ll_sock_current->id); } else if (nTemp == SOCKET_ERROR) { // client error Cns_Addline("Client error in linked list Sendall()"); } else { // client quit // client closed connection before we could reply to // all the data it sent, so bomb out early. Cns_Addline("Peer unexpectedly dropped connection!" ); } } ll_sock_current = ll_sock_current->next; // read next socket } free(data); data = NULL; } void LL_Sockets_Cleanup() { LL_SOCKETS *temp; LL_SOCKETS *ll_sock_current = NULL; // current read pointer ll_sock_current = ll_sock_start; // set current read pointer to first socket in list while (ll_sock_current) { temp = ll_sock_current; free(ll_sock_current); ll_sock_current = temp->next; free(temp); } } |