Echo function in a TCP Server-Client

Hello,
I am not an experienced programmer and especially in network programming.
I've been asked from my associates to build in classes a simple TCP client server and make an echo function within the server. I tried to implement MSDN's code
https://msdn.microsoft.com/en-us/library/windows/desktop/ms737593%28v=vs.85%29.aspx

The following code is splitted in two projects and I am using the winsock2 library. When I run the projects, I get the number of bytes for the first send and receive but it seems that the update is not working. Anyone has a clue?

PS:It is my first post ever in a forum like this, so please forgive me if I am not fulfilling the standards of a post (i.e. minimum info).

Client.h
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
#pragma once

#include <iostream>
#include <winsock2.h>

class Client
{
public:

	//Constructor/Deconstructor.
	Client(void);
	~Client(void);
	void update();

	//Structure creation for socket data space.
	sockaddr_in peer;


	
private:
	WSADATA wsaData;	
	int iResult;
	SOCKET connectsocket;
	char receivebuffer;
	char* sendbuf;
	int recvbuflen;
	//For version identifying.
	WORD wVersionRequested;




};


Client.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
#include "Client.hpp"

using namespace std;

//Constructor.
Client::Client(void):
sendbuf("This is a test\n"),
receivebuffer(512),
iResult(0),
recvbuflen(512)

{
	wVersionRequested = MAKEWORD(2, 0);

	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0) {
		printf("WSAStartup failed with error: %d\n", iResult);
	}

	peer.sin_family = AF_INET;
	peer.sin_port = htons(9171);	// port 9171
	peer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	// Create transfer socket
	connectsocket = socket(AF_INET, SOCK_STREAM, 0);

	if (connectsocket == INVALID_SOCKET) 
	{
		cerr << "Create socket failed" << endl;
		WSACleanup();
	}
	//Establishes a connection.
	if (connect(connectsocket, (sockaddr *)&peer, sizeof(peer)) == SOCKET_ERROR) 
	{
		cerr << "Connect to peer failed with " << WSAGetLastError() << endl;
	}

	//Sends data.
	iResult = send(connectsocket, sendbuf, (int)strlen(sendbuf), 0);
	if (iResult == SOCKET_ERROR) 
	{
		printf("send failed with error: %d\n", WSAGetLastError());
		closesocket(connectsocket);
		WSACleanup();
	}
	printf("Bytes Sent: %ld\n", iResult);

	// shutdown the connection since no more data will be sent
	iResult = shutdown(connectsocket, SD_SEND);
	if (iResult == SOCKET_ERROR) {
		printf("shutdown failed with error: %d\n", WSAGetLastError());
		closesocket(connectsocket);
		WSACleanup();
	}
	//Receives data.
	iResult = recv(connectsocket, &receivebuffer, recvbuflen, 0);
	if (iResult > 0)
		printf("Bytes received: %d\n", iResult);
	else if (iResult == 0)
		printf("Connection closed\n");
	else
		printf("recv failed with error: %d\n", WSAGetLastError());
	
		cout << "Message= " << receivebuffer << endl;
	
	// Cleanup windows sockets
	WSACleanup();
}
//End of constructor.

Client::~Client()
{

}

void Client::update()
{
	// Receive until the peer closes the connection
	do {

		iResult = recv(connectsocket, &receivebuffer, recvbuflen, 0);
		if (iResult > 0)
			printf("Bytes received: %d\n", iResult);
		else if (iResult == 0)
			printf("Connection closed\n");
		else
			printf("recv failed with error: %d\n", WSAGetLastError());

	} while (iResult > 0);


	// cleanup
	closesocket(connectsocket);
	WSACleanup();

}


Server.h
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
#pragma once

#include <iostream>
#include <winsock2.h>

class Server
{
public:
	//Constructor/Deconstructor.
	Server(void);
	~Server(void);
	void update();

	//The structure.
	sockaddr_in peer;

private:
	WORD wVersionRequested;
	WSADATA wsaData;
	SOCKET listensocket;
	SOCKET clientsocket;
	char receivebuffer;
	int recvbuflen;
	int iResult;
	int iSendResult;
};


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
#include "Server.hpp"

using namespace std;

//Constructor declaration.
Server::Server():
receivebuffer(512),
recvbuflen(512),
listensocket(INVALID_SOCKET),
clientsocket(INVALID_SOCKET)
{
	wVersionRequested = MAKEWORD(2, 0);

	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0) {
		printf("WSAStartup failed with error: %d\n", iResult);
	}

	peer.sin_family = AF_INET;
	peer.sin_port = htons(9171);	// port 9171
	peer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

	

	// Create a SOCKET for connecting to server
	listensocket = socket(peer.sin_family, SOCK_STREAM, 0);
	if (listensocket == INVALID_SOCKET) {
		printf("socket failed with error: %ld\n", WSAGetLastError());
		WSACleanup();
	}

	// Setup the TCP listening socket
	iResult = bind(listensocket, (sockaddr *)&peer, sizeof(peer));
	if (iResult == SOCKET_ERROR) {
		printf("bind failed with error: %d\n", WSAGetLastError());
		closesocket(listensocket);
		WSACleanup();
	}
	iResult = listen(listensocket, SOMAXCONN);
	if (iResult == SOCKET_ERROR) {
		printf("listen failed with error: %d\n", WSAGetLastError());
		closesocket(listensocket);
		WSACleanup();
	}
	
	// Accept a client socket
	clientsocket = accept(listensocket, NULL, NULL);
	if (clientsocket == INVALID_SOCKET) {
		printf("accept failed with error: %d\n", WSAGetLastError());
		closesocket(listensocket);
		WSACleanup();
	}

	closesocket(listensocket);
	
	iResult = recv(clientsocket, &receivebuffer, recvbuflen, 0);
	if (iResult > 0) 
	{
		printf("Bytes received: %d\n", iResult);
	
	}
	

	// Delay
	cout << "Waiting..." << endl; char ch; cin >> ch;

	// Cleanup windows sockets
	WSACleanup();
}

Server::~Server()
{

}

void Server::update()
{
	// Receive until the peer shuts down the connection
	do {

		iResult = recv(clientsocket, &receivebuffer, recvbuflen, 0);
		if (iResult > 0) {
			printf("Bytes received: %d\n", iResult);

			// Echo the buffer back to the sender
			iSendResult = send(clientsocket, &receivebuffer, iResult, 0);
			if (iSendResult == SOCKET_ERROR) {
				printf("send failed with error: %d\n", WSAGetLastError());
				closesocket(clientsocket);
				WSACleanup();
			}
			printf("Bytes sent: %d\n", iSendResult);
		}
		else if (iResult == 0)
			printf("Connection closing...\n");
		else  {
			printf("recv failed with error: %d\n", WSAGetLastError());
			closesocket(clientsocket);
			WSACleanup();
		}

	} while (iResult > 0);

	// shutdown the connection since we're done
	iResult = shutdown(clientsocket, SD_SEND);
	if (iResult == SOCKET_ERROR) {
		printf("shutdown failed with error: %d\n", WSAGetLastError());
		closesocket(clientsocket);
		WSACleanup();
	}
}


Servermain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <winsock2.h>
#include "Server.hpp"

// TCP SERVER

using namespace std;
void serverLoop(void);
Server* server;

int main(int, char**) {
	
	server = new Server();
	
	serverLoop();
}

void serverLoop()
{
	while (true)
	{
		server->update();
	}
}


Clientmain
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
#include <iostream>
#include <winsock2.h>
#include "Client.hpp"

// TCP CLIENT

using namespace std;

void clientLoop(void);
Client* client;

int main(int, char**) 
{
	client = new Client();

	clientLoop();
}

void clientLoop()
{
	while (true)
	{
		//do game stuff
		client->update();
	}
}
Last edited on
closed account (3hM2Nwbp)
Your receive buffer is of type char? Perhaps you meant char* and then dynamically allocating it in your constructors? Don't forget to deallocate it in your destructor!

*aside from the obvious, I'm afraid that I can't help much more as I haven't (and shall not in the future) use a non portable networking API like winsock.
Last edited on
Thank you for your response. I've tried what you suggested, but unfortunately it did not work. I am still receiving only the first messages and then I get weird things and errors.
http://imgur.com/OB19lWr,qr8jOSL#0
Topic archived. No new replies allowed.