[Sockets, Win32 API]Chat Client massive amount of errors - followed book

Pages: 12
Hello,

I've bought a book about sockets approx 1 month ago and now I've tried to make chat client, there is already client and server created so I just tried to "copy" his communication to my chat, however, I'm getting a lot of errors

I'll put all codes on pastebin because it's a lot of lines!

my chat source code:

http://pastebin.com/i4jQRG1X

//there are few testing things, like button1 for reading from resource txt file, combo box etc, just ignore that for now

errors:

http://pastebin.com/a6Pc3XgX

chat client from book:

http://pastebin.com/Ujedx5MA

this client compiles fine.

I'm using multi-byte character set so that's maybe the problem, but before I rewrite my whole program to unicode I wanna from someone who actually can help me to take a look at this before I do that

some answers to the questions you will probably ask:

1. Yes I have linked ws2_32.lib
2. Yes I've tried to solve those errors
3. Yes my program was fine before I implemented sockets
Last edited on
From "C++ Redefinition Header Files"
http://stackoverflow.com/questions/1372480/c-redefinition-header-files

c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(91) : warning C4005: 'AF_IPX' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(460) : see previous definition of 'AF_IPX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(124) : warning C4005: 'AF_MAX' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(479) : see previous definition of 'AF_MAX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(163) : warning C4005: 'SO_DONTLINGER' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(402) : see previous definition of 'SO_DONTLINGER'
(etc)


This problem is caused when including <windows.h> before <winsock2.h>. Try arrange your include list that <windows.h> is included after <winsock2.h> or define _WINSOCKAPI_ first: ...

Worth a try?
1
2
3
4
5
6
7
8
9
#include "resource.h"
#include <string>
#include <mysql++.h>
#include <manip.h> 
#include <sstream>
#include <fstream>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <Windows.h> 


and I'm still getting same errors :X
Do any of the other headers before winsock2.h include windows.h?

Have you tried including winsock2.h first?

The errors and warnings you're getting do suggest you're including both the old winsock.h and winsock2.h

(I don't have a compiler handy to check... just a "toy" to check my mail and browse)
Last edited on
after arranging it like this:

1
2
3
4
5
6
7
8
9
10
#include <winsock2.h>
#include <Windows.h>
#include "resource.h"
#include <string>
#include <mysql++.h>
#include <manip.h> 
#include <sstream>
#include <fstream>
#include <winsock2.h>
#include <Ws2tcpip.h> 


I'm no more getting any errors, thanks a lot ! :)

edit: well, there is something broken, I've remaked my append text a little so I will make wholeMessage first (with name, message and colors etc) and then send it to the server, BUT, after using stringstream and converting it to char, it won't convert it with spaces ofc, what can I do? here is the edited code:

http://pastebin.com/i4jQRG1X

as u can see, I've used fstream to get the "error", and I'm getting this output:

1
2
{\rtf1\ansi\ansicpg0\deff0{\colortbl;\red0\green0\blue0;\red255\green0\blue0;}\cf2 SEnergy\cf1 : test\line}
{\rtf1\ansi\ansicpg0\deff0{\colortbl;\red0\green0\blue0;\red255\green0\blue0;}\cf2


so yea, right after space it ends, is there anyway how to make char containing spaces too (I've had troubles with this everytime, well, I never figured it out) or how can I fix it?
Last edited on
operator>> only reads till the first space, tab or endline, so that's what ss >> buffer; is doing.

ss.getline(buffer, _countof(buffer)); will read as many chars will fit in the buffer, or up to the first endline. Which ever appears first.

getline() has a third param which defaults to '\n', in case you want to stop at the first (e.g.) ','

Andy
Last edited on
well, I mean this part:
1
2
3
stringstream ss;
ss << MakeText(buffer);
ss >> buffer;


where MakeText returns string, and buffer is a char array because send() function can't use strings, and getline don't works for wholeMessage.c_str

so I need any way on how to convert string with spaces to char buffer[1024000]
Last edited on
If wholeMessage is a std::string, use

getline(ss, wholeMessage);

(this getline is a function, not a method of istream)
well, yea, I exactly know what getline() is for, I was using it before, but with console applications only

so now I have this

1
2
3
stringstream ss;
ss << MakeText(buffer);
getline(ss, buffer);


and i have this errors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2784: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::stringstream'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(479) : see declaration of 'std::getline'
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2784: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::stringstream'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(479) : see declaration of 'std::getline'
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2784: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'std::basic_string<_Elem,_Traits,_Alloc> &' from 'char [102400]'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(479) : see declaration of 'std::getline'
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2780: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' : expects 3 arguments - 2 provided
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(468) : see declaration of 'std::getline'
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2784: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &&,std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &&' from 'std::stringstream'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(448) : see declaration of 'std::getline'
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2784: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &&,std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &&' from 'std::stringstream'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(448) : see declaration of 'std::getline'
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2784: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &&,std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'std::basic_string<_Elem,_Traits,_Alloc> &' from 'char [102400]'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(448) : see declaration of 'std::getline'
1>c:\users\mekkatorqu\documents\visual studio 2010\projects\chat\win32game\main.cpp(360): error C2780: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &&,std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' : expects 3 arguments - 2 provided
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string(395) : see declaration of 'std::getline'


I need to get value FROM wholeMessage and give it TO buffer
The global function version of getline is for use with strings:
http://www.cplusplus.com/reference/string/getline/

1
2
3
4
string str;
stringstream ss;
ss << MakeText(buffer);
getline(ss, str);


For a buffer, you need to use the member function version
http://www.cplusplus.com/reference/iostream/istream/getline/

1
2
3
4
string str;
stringstream ss;
ss << MakeText(buffer);
ss.getline(buffer, _countof(buffer));


But personally, I would not bother with stringstream here as it's just string -> string, rather than formatting or reading numbers, etc

As MakeText returns a string, you could just use strncpy
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

1
2
3
memset(buffer, 0, sizeof(buffer));
string str = MakeText(buffer);
strncpy(buffer, str.c_str(), _countof(buffer) - 1);


Andy

PS I am using strncpy rather than strcpy, to avoid buffer overruns. And zeroing the buffer.

PPS sizeof() returns the size in bytes, whereas _countof() -- VC++ specific -- is the same as sizeof(a)/sizeof(a[0]), which is the number of elements in the array. It's a good habit because sizeof() != _countof() for wchar_t arrays.
Last edited on
my output now contains name with Color, but without message:

http://filebeam.com/237d67f8e75ad470d746cebe8bacfb98.jpg

1
2
3
memset(buffer, 0, sizeof(buffer));
string str = MakeText(buffer);
strncpy(buffer, str.c_str(), _countof(buffer) - 1);
Oops! Swap the first two lines.

Sorry!
no problem :) nice, it's working, but I have another problem, this one is because of server I guess

server source code:

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
170
171
172
173
174
175
#include <winsock2.h>
#include <windows.h>
#include <string.h>

#define BUFSIZE 1024
#define MAX_SOCKETS 100
#define TCP_PORT 5000
#define TEXT_SIZE 102400

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
void OnFD_ACCEPT(SOCKET s);
void OnFD_READ(SOCKET s);
void OnFD_CLOSE(SOCKET s);
void sendData(char buffer[TEXT_SIZE], int lenght, SOCKET from);

int socketCount = 0;
SOCKET mainSocket;
HWND mainHwnd;
SOCKET sockets[MAX_SOCKETS];

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil){
    MSG messages;
    WNDCLASSEX wincl;

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = TEXT("SocketServer");
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if (!RegisterClassEx (&wincl))
        return 0;

    mainHwnd = CreateWindowEx (0, TEXT("SocketServer"), TEXT("Server"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,  CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
    ShowWindow (mainHwnd, nFunsterStil);

    while (GetMessage (&messages, NULL, 0, 0)){
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
	int p;
	WORD wVersionRequested = MAKEWORD(2,2);
    WSADATA data;
	struct sockaddr_in myAddr;
    switch (message){
        case WM_DESTROY:
                for(p = 0; p < MAX_SOCKETS; p++){
					closesocket(sockets[p]);
				}
                closesocket(mainSocket);
				WSACleanup();
                PostQuitMessage (0);
                break;
		case WM_CREATE:
			if (WSAStartup(wVersionRequested, &data) != 0){
				return 0;
			}
			if ((mainSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
				return 0;
			}
			myAddr.sin_family = AF_INET;
			myAddr.sin_port = htons(TCP_PORT);
			myAddr.sin_addr.s_addr = INADDR_ANY;
			if ((bind(mainSocket, (struct sockaddr*)&myAddr, sizeof(struct sockaddr_in))) == SOCKET_ERROR){
				return 0;
			}
			if (WSAAsyncSelect(mainSocket, hwnd, WM_USER + 1, FD_ACCEPT) == SOCKET_ERROR){
				return 0;
			}
			if (listen(mainSocket, 10) == SOCKET_ERROR){
				return 0;
			}
			break;
        case WM_USER + 1:
                switch (WSAGETSELECTEVENT(lParam)){
                   case FD_ACCEPT:
                        OnFD_ACCEPT((SOCKET)wParam);
                        break;
                   case FD_READ:
                        OnFD_READ((SOCKET)wParam);
                        break;
                   case FD_CLOSE:
                        OnFD_CLOSE((SOCKET)wParam);
                        break;
                }
                break;
        default:
                return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

void OnFD_ACCEPT(SOCKET s){
	struct sockaddr_in remonteAddr;
	int lenght = sizeof(remonteAddr);
    SOCKET newSocket = accept(s, (struct sockaddr *)&remonteAddr, &lenght);
    char buffer[BUFSIZE];
    if (newSocket == INVALID_SOCKET){
        return;
    }
    if (WSAAsyncSelect(newSocket, mainHwnd, WM_USER + 1, FD_READ | FD_CLOSE) == SOCKET_ERROR){
        shutdown(newSocket, SD_BOTH);
        closesocket(newSocket);
    }
    else{
    	if (socketCount >= MAX_SOCKETS){
    		strncpy(buffer, "Bohužel, je vás hodně.", BUFSIZE);
    		send(s, buffer, strlen(buffer), 0);
    		shutdown(s, SD_BOTH);
    		closesocket(s);
    	}
    	else{
    		sockets[socketCount++] = newSocket;
    	}
    }
}

void OnFD_READ(SOCKET s){
    int size, i, j;
    char buffer[BUFSIZE];
    if ((size = recv(s, buffer, BUFSIZE, 0)) == SOCKET_ERROR){
        WSAAsyncSelect(s, mainHwnd, 0, 0);
        strncpy(buffer, "Nemohu přijmout data", BUFSIZE);
        send(s, buffer, strlen(buffer), 0);
        shutdown(s, SD_BOTH);
        closesocket(s);
        for(i = 0; i < socketCount; i++){
        	if (sockets[i] == s){
        		for(j = i; j < socketCount - 1; j++){
        			sockets[j] = sockets[j + 1];
        		}
        		socketCount--;
        		break;
        	}
        }
        return;
    }
    sendData(buffer, size, s);
}

void OnFD_CLOSE(SOCKET s){
	int i, j;
    WSAAsyncSelect(s, mainHwnd, 0, 0);
    closesocket(s);
    for(i = 0; i < socketCount; i++){
    	if (sockets[i] == s){
    		for(j = i; j < socketCount - 1; j++){
    			sockets[j] = sockets[j + 1];
            }
            socketCount--;
            break;
        }
    }
}

void sendData(char buffer[TEXT_SIZE], int length, SOCKET from){
	int p;
	for(p = 0; p < socketCount; p++){
		if (sockets[p] != from){
			send(sockets[p], buffer, length+1, 0);
		}
	}
}


this server is from book, I modified it a little and I'm using it with my chat client, connection works, but sending messages is broken

I've created 2 accs, 'Test' and 'SEnergy', SEnergy is admin,

I ran chat client 2 times and logged in with both accounts

test sended message "test1" and SEnergy sended message "test2", here is the result:

http://filebeam.com/7fbbc089622a07434a14ac8ef2bacdb1.jpg
I am unclear about what the images mean.

And the code is rather involved. What I suggest you do as a next step is add logging code to your server so it writes a log file. (You could even write the log file to the server window?)

Last edited on
well, how I said, logging works, but sending messages is broken, first window is "test" user, second window is "senergy" user, as u can see, if someone else sends message, I'll get only "{\rt" from server, but if I write message, I'll get it normally (SEnergy: test2/test: test1), but others will get it broken as I mentioned already

so:

1. we have 2 users on chat, SEnergy and test
2. test will send "hello" message
3. senergy will receive "{\rt"
4. test will receive "hello"

and vice versa
I take it that you get the message directly (without going via the server) when you send it? (I see the server does not send to the socket is just received from).

Have you added logging to the server, that writes what it receives and sends to a log file? The code as posted shows no signs of it.

If you haven't already done so, I would mean adding code to the OnFD_READ and sendData functions that logs the receives and send. (While you're at it, I would add logging for all key event).

Andy

P.S. I would prob use fprintf for debug logging, as it's easy to swap out (than << style logging) later on using macros.
Last edited on
yes I'm trying to make log for my server now, I've rewrote server so it's dialog now with read-only edit box, here is source code:

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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include <winsock2.h>
#include <windows.h>
#include <string.h>
#include "resource.h"

#define BUFSIZE 1024
#define MAX_SOCKETS 100
#define TCP_PORT 5000
#define TEXT_SIZE 102400

#define MY_WM_INITDIALOG (WM_USER + 2)

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
void OnFD_ACCEPT(SOCKET s);
void OnFD_READ(HWND hWnd, SOCKET s);
void OnFD_CLOSE(SOCKET s);
void sendData(char buffer[TEXT_SIZE], int lenght, SOCKET from);

int socketCount = 0;
SOCKET mainSocket;
HWND mainHwnd;
SOCKET sockets[MAX_SOCKETS];

INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, INT nShowCmd)
{
	UNREFERENCED_PARAMETER(hPrevInst);
	UNREFERENCED_PARAMETER(lpCmdLine);

	WNDCLASSEX wClass;
	wClass.cbClsExtra=NULL;
	wClass.cbSize=sizeof(WNDCLASSEX);
	wClass.cbWndExtra=DLGWINDOWEXTRA;
	wClass.hbrBackground=(HBRUSH)(COLOR_BTNFACE + 1);
	wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
	wClass.hIcon=NULL;
	wClass.hIconSm=NULL;
	wClass.hInstance=hInst;
	wClass.lpfnWndProc=WindowProcedure;
	wClass.lpszClassName=TEXT("chat Server");
	wClass.lpszMenuName=NULL;
	wClass.style=CS_HREDRAW | CS_VREDRAW;

	if(!RegisterClassEx(&wClass))
	{
		int nResult = GetLastError();
		MessageBox(NULL, TEXT("Window Class Creation Failed!"), NULL, MB_ICONERROR | MB_OK);
		return 0;
	}

	mainHwnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL);

	if(!mainHwnd)
	{
		int nResult = GetLastError();
		MessageBox(NULL, TEXT("Dialog Creation Failed!"), NULL, MB_ICONERROR | MB_OK);
		return 0;
	}

	MSG msg;
	ZeroMemory(&msg,sizeof(MSG));

	while(GetMessage(&msg, NULL, 0, 0) == TRUE)
	{
		if(!IsDialogMessage(mainHwnd, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return msg.wParam;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
	int p;
	WORD wVersionRequested = MAKEWORD(2,2);
    WSADATA data;
	struct sockaddr_in myAddr;
    switch (message){
        case WM_DESTROY:
                for(p = 0; p < MAX_SOCKETS; p++){
					closesocket(sockets[p]);
				}
                closesocket(mainSocket);
				WSACleanup();
                PostQuitMessage (0);
                break;
		case WM_CREATE:
			PostMessage(hwnd, MY_WM_INITDIALOG, 0, 0);
			break;
		case MY_WM_INITDIALOG:
			{
				if (WSAStartup(wVersionRequested, &data) != 0){
				return 0;
			}
			if ((mainSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
				return 0;
			}
			myAddr.sin_family = AF_INET;
			myAddr.sin_port = htons(TCP_PORT);
			myAddr.sin_addr.s_addr = INADDR_ANY;
			if ((bind(mainSocket, (struct sockaddr*)&myAddr, sizeof(struct sockaddr_in))) == SOCKET_ERROR){
				return 0;
			}
			if (WSAAsyncSelect(mainSocket, hwnd, WM_USER + 1, FD_ACCEPT) == SOCKET_ERROR){
				return 0;
			}
			if (listen(mainSocket, 10) == SOCKET_ERROR){
				return 0;
			}
			}
        case WM_USER + 1:
                switch (WSAGETSELECTEVENT(lParam)){
                   case FD_ACCEPT:
                        OnFD_ACCEPT((SOCKET)wParam);
                        break;
                   case FD_READ:
                        OnFD_READ(hwnd, (SOCKET)wParam);
                        break;
                   case FD_CLOSE:
                        OnFD_CLOSE((SOCKET)wParam);
                        break;
                }
                break;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

void OnFD_ACCEPT(SOCKET s){
	struct sockaddr_in remonteAddr;
	int lenght = sizeof(remonteAddr);
    SOCKET newSocket = accept(s, (struct sockaddr *)&remonteAddr, &lenght);
    char buffer[BUFSIZE];
    if (newSocket == INVALID_SOCKET){
        return;
    }
    if (WSAAsyncSelect(newSocket, mainHwnd, WM_USER + 1, FD_READ | FD_CLOSE) == SOCKET_ERROR){
        shutdown(newSocket, SD_BOTH);
        closesocket(newSocket);
    }
    else{
    	if (socketCount >= MAX_SOCKETS){
    		strncpy(buffer, "Bohužel, je vás hodně.", BUFSIZE);
    		send(s, buffer, strlen(buffer), 0);
    		shutdown(s, SD_BOTH);
    		closesocket(s);
    	}
    	else{
    		sockets[socketCount++] = newSocket;
    	}
    }
}

void OnFD_READ(HWND hWnd, SOCKET s){
    int size, i, j;
    char buffer[TEXT_SIZE];
    if ((size = recv(s, buffer, BUFSIZE, 0)) == SOCKET_ERROR){
        WSAAsyncSelect(s, mainHwnd, 0, 0);
        strncpy(buffer, "Nemohu přijmout data", BUFSIZE);
        send(s, buffer, strlen(buffer), 0);
        shutdown(s, SD_BOTH);
        closesocket(s);
        for(i = 0; i < socketCount; i++){
        	if (sockets[i] == s){
        		for(j = i; j < socketCount - 1; j++){
        			sockets[j] = sockets[j + 1];
        		}
        		socketCount--;
        		break;
        	}
        }
        return;
    }
	HWND hwndOutput = GetDlgItem(hWnd, IDC_EDIT1);
	int textLen = SendMessage(hwndOutput, WM_GETTEXTLENGTH, 0, 0);
	SendMessage(hwndOutput, EM_SETSEL, textLen, textLen);
	SendMessage(hwndOutput, EM_REPLACESEL, TRUE, (LPARAM)buffer);
	SendMessage(hwndOutput, WM_VSCROLL, SB_BOTTOM, NULL);
    sendData(buffer, size, s);
}

void OnFD_CLOSE(SOCKET s){
	int i, j;
    WSAAsyncSelect(s, mainHwnd, 0, 0);
    closesocket(s);
    for(i = 0; i < socketCount; i++){
    	if (sockets[i] == s){
    		for(j = i; j < socketCount - 1; j++){
    			sockets[j] = sockets[j + 1];
            }
            socketCount--;
            break;
        }
    }
}

void sendData(char buffer[TEXT_SIZE], int length, SOCKET from){
	int p;
	int testl = sizeof(buffer) / sizeof(buffer[0]);
	for(p = 0; p < socketCount; p++){
		if (sockets[p] != from){
			send(sockets[p], buffer, testl, 0);
		}
	}
}


and I changed WM_DNS in client so it now sends message to everyone if someone has connected and write it in edit box, however, It's NOT writing it to dialog, it will just again send weird text to everyone

here is the client WM_DNS

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
	case WM_DNS:
		{
			if(idTask == (HWND)wParam)
			{
				struct hostent *host = (struct hostent *) buf;
				struct sockaddr *addr = NULL;
				struct sockaddr_in addr_ip4;
				size_t addrLen = 0;
				if(WSAGETASYNCERROR(lParam) != 0)
				{
					return 0;
				}
				addr_ip4.sin_family = host->h_addrtype;
				addr_ip4.sin_port = htons(TCP_PORT);
				memcpy(&(addr_ip4.sin_addr), host->h_addr_list[0], host->h_length);
				addr = (struct sockaddr *)&addr_ip4;
				addrLen = sizeof(addr_ip4);
				if ((sock = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
					return 0;
				}
				if (connect(sock, addr, addrLen) == SOCKET_ERROR){
					return 0;
				}
				if (WSAAsyncSelect(sock, hMain, WM_DATA, FD_READ) == SOCKET_ERROR){
					return 0;
				}
			}
			char buffer[TEXT_SIZE];
			wsprintf(buffer, "%s has connected to server", Username);
			if(send(sock, buffer, strlen(buffer), 0) == SOCKET_ERROR)
			{
				MessageBox(hMain, "Error", "Error", MB_OK);
				return 0;
			}
		}


edit: yes it will post my server directly to me when I send it (without going via server)
Last edited on
So do you now know what the server reads from the socket?

And what it sends on?

It's later here, so my brain is beginning to shut down.

Andy

P.S. I can see places where you're sending strings without their null terminators (i.e. strlen() cf strlen() + 1). I'm not saying this is wrong, as I haven't followed the code through. But is is quite common to include null terminators when sending/saving strings as binary.
okay, I've fixed almost everything now,

I've replaced int size = GetWindowTextLength(IDC_MESSAGE1); (or something like that, I don't remember exactly what was there) in client with

int size = strlen(buffer);

and same thing I did in the server, and everything works fine! :)

edit: but there is still something wrong,

1
2
3
4
5
6
char buffer[] = "ahoj";
				HWND hwndOutput = GetDlgItem(hwnd, IDC_EDIT1);
				int textLen = SendMessage(hwndOutput, WM_GETTEXTLENGTH, 0, 0);
				SendMessage(hwndOutput, EM_SETSEL, textLen, textLen);
				SendMessage(hwndOutput, EM_REPLACESEL, TRUE, (LPARAM)buffer);
				SendMessage(hwndOutput, WM_VSCROLL, SB_BOTTOM, NULL);


is doing this:

http://filebeam.com/252d1a3e87a2f8412a1319bfafc366eb.jpg
Last edited on
No idea. The code looks fine (this code has been around a while, yes?)

Is the returned textLen what you expect?
Try retrieving the existing text, to see what's being added to.
Pages: 12