c++ socket client implementation - c++

I have maybe a strange problem, but I can't get sockets working. I need to connect c++ app with node.js server, which has open socket. I have tried many sources, but none of them are working. One of that, that I have at the moment:
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "3000"
int sock()
{
int argc = 2;
const char* argv[3];
argv[0] = "127.0.0.1";
argv[1] = "127.0.0.1";
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo* result = NULL,
* ptr = NULL,
hints;
const char* sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
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();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, 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();
return 0;
}
This is official microsoft code for the winsock client. Also, I have tried socket client code from here: https://www.geeksforgeeks.org/socket-programming-cc/
From the microsoft code I am getting that, data was sent, but node.js console remains empty: https://prnt.sc/zdhpsi
Node.js server code:
var port = 3000;
var io = require('socket.io')().listen(port);
console.log("Listening on port " + port);
/* Socket.IO events */
io.on("connection", function(socket){
console.log("new connection");
socket.on('test_text', (...args) => {
console.log("test text event received.", args);
});
socket.on('test_binary', (...args) => {
console.log("test binary event received", args);
if(args[0] instanceof Buffer)
{
console.log("test binary event received,binary length:"+ args[0].length);
}
});
socket.on('test ack',function()
{
var args =Array.prototype.slice.call(arguments);
if('object' == typeof args[0])
{
console.log("test combo received,object:");
console.log(JSON.stringify(args[0]));
}
if(args.length>1 && 'function' == typeof args[args.length - 1])
{
console.log('need ack for test combo');
var fn = args[args.length - 1];
fn('Got bin length:' + args[0].bin.length);//invoke ack callback function.
}
});
});
On c++ side I don't need to recieve anything, I just need to send the data
Maybe you know how this could be done? Thanks :)

Related

WTSEnumerateProcesses with socket and data struct

I'm new with C++ Windows API and I've got few questions about using the WTSEnumerateProcesses() API.
My target: use WTSEnumerateProcesses(), take only the process list, put it in any kind of "list" or struct, convert the widechar to ANSI, and send it to a socket using Winsock.
That's my code below:
Winsock:
int connect(char buffer[])
{
PCSTR ip = "localhost";
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
const char *sendbuf =buffer;
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(ip, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
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();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, 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();
return 0;
}
and the WTSEnumerateProcesses():
void GetProcesslist()
{
vector<LPWSTR> v; // no need to prepend std:: any more
LPWSTR pProcessName;
WTS_PROCESS_INFO* pWPIs = NULL;
DWORD dwProcCount = 0;
if (WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWPIs, &dwProcCount))
{
//Go through all processes retrieved
for (DWORD i = 0; i < dwProcCount; i++)
{
pProcessName = pWPIs[i].pProcessName;
v[i] = pProcessName;
//contains(pProcessName);
// process file name only, no path!
//data = pProcessName;
std::wcout << pProcessName << endl;
//pWPIs[i].ProcessId = process ID
//pWPIs[i].SessionId = session ID, if you need to limit it to the logged in user processes
//pWPIs[i].pUserSid = user SID that started the process
}
}
//Free memory
if (pWPIs)
{
WTSFreeMemory(pWPIs);
pWPIs = NULL;
}
}
Can you please help me to understand how I can take the process list only, push it to any struct (like a list?) and send it correctly over the TCP socket, that is waiting to get a const char[] and not wide characters?
You are not using std::vector correctly in your GetProcesslist(). You are trying to access elements you have not allocated any memory for. And worse, you are storing pointers to data that you free before GetProcesslist() exits, leaving the vector containing dangling pointers (were you to access that vector outside of GetProcesslist(), which you are not doing yet).
Try something more like this:
std::vector<std::wstring> GetProcesslist()
{
std::vector<std::wstring> v;
WTS_PROCESS_INFO* pWPIs = NULL;
DWORD dwProcCount = 0;
if (WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWPIs, &dwProcCount))
{
//Go through all processes retrieved
for (DWORD i = 0; i < dwProcCount; ++i)
{
LPWSTR pProcessName = pWPIs[i].pProcessName;
v.push_back(pProcessName);
// process file name only, no path!
//data = pProcessName;
std::wcout << pProcessName << endl;
//pWPIs[i].ProcessId = process ID
//pWPIs[i].SessionId = session ID, if you need to limit it to the logged in user processes
//pWPIs[i].pUserSid = user SID that started the process
}
//Free memory
WTSFreeMemory(pWPIs);
}
return v;
}
Then, I would suggest sending the data over the socket like this:
int connect(const char buffer[], size_t buffersize)
{
PCSTR ip = "localhost";
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
const char *sendbuf = buffer;
char recvbuf[DEFAULT_BUFLEN];
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(ip, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
while (buffersize > 0) {
iResult = send(ConnectSocket, sendbuf, (int)buffersize, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
sendbuf += iResult;
buffersize -= 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();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, sizeof(recvbuf), 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();
return 0;
}
std::vector<std::wstring> procs = GetProcesslist();
std::vector<char> buffer;
size_t size = sizeof(uint32_t);
for(const std::wstring &name : procs) {
size += (sizeof(uint32_t) + WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name.size(), NULL, 0, NULL, NULL));
}
buffer.resize(size);
char *ptr = buffer.data();
*reinterpret_cast<uint32_t*>(ptr) = htonl(procs.size());
ptr += sizeof(uint32_t);
for(const std::wstring &name : procs) {
int len = WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name.size(), NULL, 0, NULL, NULL));
*reinterpret_cast<uint32_t*>(ptr) = htonl(len);
ptr += sizeof(uint32_t);
if (len > 0) {
ptr += WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name.size(), ptr, len, NULL, NULL));
}
}
connect(buffer.data(), buffer.size());
Or, if you absolutely cannot change the signature of connect() and must pass it a null-terminated C string, then try this:
int connect(const char buffer[])
{
PCSTR ip = "localhost";
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
const char *sendbuf = buffer;
sendbuflen = strlen(buffer);
char recvbuf[DEFAULT_BUFLEN];
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(ip, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
while (sendbuflen > 0) {
iResult = send(ConnectSocket, sendbuf, sendbuflen, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
sendbuf += iResult;
sendbuflen -= 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();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, sizeof(recvbuf), 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();
return 0;
}
std::vector<std::wstring> procs = GetProcesslist();
std::ostringstream oss;
oss << procs.size() << "\x1";
for(const std::wstring &name : procs) {
int len = WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name.size(), NULL, 0, NULL, NULL);
if (len > 0) {
std::string s;
s.resize(len);
WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name.size(), &s[0], len, NULL, NULL);
oss << s;
}
oss << "\x1";
}
connect(oss.str().c_str());

WinSock2 c++ what happens when accept(...) method is called

I am following the Getting Started with WinSock guide (here) from Microsoft.
In my situation I have a java application that act as the client, and a c++ application for the server.
Here is the server code so far:
//all includes
int main()
{
WSADATA wsaData;
int iResult;
SOCKET listenSocket = INVALID_SOCKET;
SOCKET clientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
//Initialization
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
else {
printf("WSAStartup success !\n");
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
//Resolve the server adress and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (listenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
//Setup the TCP listening socket
iResult = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(listenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(listenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(listenSocket);
WSACleanup();
return 1;
}
clientSocket = accept(listenSocket, NULL, NULL);
if (clientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(listenSocket);
WSACleanup();
return 1;
}
//No longer need server socket
closesocket(listenSocket);
// Receive until the peer shuts down the connection
do {
iResult = recv(clientSocket, recvbuf, recvbuflen, 0);
printf("result : %d", iResult);
//Receive data
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
printf("Message: %s\n Sending response to client... ", recvbuf);
const char* response = "Hello from key/mouse emulator app server";
iSendResult = send(clientSocket, response, sizeof(char) * (strlen(response)+1), 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
return 1;
}
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();
return 1;
}
} 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();
return 1;
}
// cleanup
closesocket(clientSocket);
WSACleanup();
system("PAUSE");
return 0;
}
My understanding was that in the do...while loop it was listening to any incoming data from the client. So I tried to debug to check what kind of values I have in iResult when nothing is sent.
I found out using Visual Studio community 2017 that I could not go further this line :
clientSocket = accept(listenSocket, NULL, NULL);
And it would only go in the do...while when the client sent some data.
So my question is what happens in the program when I reach accept(...) line?

Winsock - Allowing multiple clients with threads [duplicate]

This question already has answers here:
TCP Winsock: accept multiple connections/clients
(2 answers)
Closed 6 years ago.
This is the code I have currently, and I'm looking into introducing threads to allow the server process multiple clients at once, however I'm having a little trouble understanding exactly how to do this. Any help would be appreciated.
Client:
int create_client()
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(DEFAULT_IP, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
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();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, 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();
return 0;
}
Server:
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
cout << "Server initalized." << endl;
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
// Receive until the peer shuts down the connection
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
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();
return 1;
}
} 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();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
You should separate the listening and the processing parts.
So, your main thread will listen the socket, and when recieve some connection create a threa.
The thread will accept the connection to have the client socket, the read and process.
Pseudocode for you main thread:
while (true){
listen the socket
if any entry connection{
create thread and process the petition
}
}
Pseudocode for you threads:
accept connection and obtain the client socket
process it
close the client socket
EDIT:
PD: This is only a temporal solution, in any real life situation that have huge petitions this won't work well.

how to send message to server from main (winsock)?

I created a simple client-server application using winsock.
I want to send message to the server as a response to the user input - but it doesnt work.
I created a function sendData() which sends "test" to the server.
If I call the func Immediately after connectind the server - it works fine, but if i call it from the main or another class - the message isn't accept by the server.
any suggestions?
Client code:
#include "StdAfx.h"
#include "CommHandler.h"
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFLEN 512
SOCKET CommHandler::m_socket = INVALID_SOCKET;
CommHandler::CommHandler(void)
{
init();
}
//===============================================================
CommHandler::~CommHandler(void)
{
// cleanup
closesocket(m_socket);
WSACleanup();
}
//===============================================================
bool CommHandler::init()
{
return (establishConnection("127.0.0.1"));
}
//===============================================================
bool CommHandler::sendData()
{
if (m_socket == INVALID_SOCKET) {
printf("send msg failed; INVALID_SOCKET: %d\n", WSAGetLastError());
return false;
}
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
// Send an initial buffer
int iResult = send(m_socket, sendbuf, (int) strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(m_socket);
WSACleanup();
return false;
}
printf("sending initial message to server!\n");
printf("Bytes Sent: %ld\n", iResult);
iResult = recv(m_socket, recvbuf, DEFAULT_BUFLEN, 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());
return true;
}
//===============================================================
bool CommHandler::establishConnection(const std::string ip)
{
return (initWinsock() && createSocket(ip));
}
//===============================================================
bool CommHandler::initWinsock()
{
// Initialize Winsock
int iResult = WSAStartup(MAKEWORD(2,2), &m_wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return false;
}
printf("WSAStartup succeeded.\n");
return true;
}
//===============================================================
bool CommHandler::createSocket(const std::string ip)
{
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
int iResult = getaddrinfo(ip.c_str(), DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return false;
}
// Attempt to connect to the first address returned by
// the call to getaddrinfo
ptr=result;
// Create a SOCKET for connecting to server
m_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (m_socket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return false;
}
printf("socket creation succeeded.\n");
// Connect to server.
iResult = connect( m_socket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
freeaddrinfo(result);
if (m_socket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return false;
}
printf("connected to server!\n");
// Send an initial buffer
sendData(); //this send data is received by the server
sendData(); //this send data is received by the server
return true;
}
Server code:
#include "StdAfx.h"
#include "CommHandler.h"
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFLEN 512
CommHandler::CommHandler(void):m_listenSocket(INVALID_SOCKET), m_clientSocket(INVALID_SOCKET)
{
}
//===============================================================
CommHandler::~CommHandler(void)
{
}
//===============================================================
bool CommHandler::init()
{
if (establishConnection()) {
return (receiveData());
}
return false;
}
//===============================================================
bool CommHandler::receiveData()
{
char recvbuf[DEFAULT_BUFLEN];
int iResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN;
// Receive until the peer shuts down the connection
do {
printf("in receiveData function\n");
iResult = recv(m_clientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
std::cout<<recvbuf<<std::endl;
// Echo the buffer back to the sender
iSendResult = send(m_clientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(m_clientSocket);
WSACleanup();
return false;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0) {
printf("Connection closing...\n");
}
else {
printf("recv failed: %d\n", WSAGetLastError());
closesocket(m_clientSocket);
WSACleanup();
return false;
}
} while (iResult > 0);
printf("exit receiveData function with no errors (finish while)\n");
return true;
}
//===============================================================
bool CommHandler::establishConnection()
{
// Initialize Winsock
int iResult = WSAStartup(MAKEWORD(2,2), &m_wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return false;
}
printf("WSAStartup succeeded.\n");
struct addrinfo *result = NULL, *ptr = NULL, hints;
ZeroMemory(&hints, sizeof (hints));
hints.ai_family = AF_INET; //used to specify the IPv4 address family
hints.ai_socktype = SOCK_STREAM; //used to specify a stream socket
hints.ai_protocol = IPPROTO_TCP; //used to specify the TCP protocol
hints.ai_flags = AI_PASSIVE;
// Resolve the local address and port to be used by the server
int iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return false;
}
// Create a SOCKET for the server to listen for client connections
m_listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (m_listenSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return false;
}
printf("socket creation succeeded.\n");
//bind the socket:
// Setup the TCP listening socket
iResult = bind( m_listenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(m_listenSocket);
WSACleanup();
return false;
}
freeaddrinfo(result);
printf("bind the socket.\n");
//listen the socket
if ( listen( m_listenSocket, SOMAXCONN ) == SOCKET_ERROR ) {
printf( "Listen failed with error: %ld\n", WSAGetLastError() );
closesocket(m_listenSocket);
WSACleanup();
return false;
}
printf("listen the socket.\n");
// Accept a client socket
m_clientSocket = accept(m_listenSocket, NULL, NULL);
if (m_clientSocket == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
closesocket(m_listenSocket);
WSACleanup();
return false;
}
printf("accept client socket.\n");
return true;
}
client's main:
int main()
{
CommHandler ch;
if (!ch.init())
return 1;
ch.sendData(); //this msg isn't received by server !!!
system("pause");
return(0);
}
Thanks!
i found the problem. I call init() functions twice and it broke the connections :|

WinSock server is able to get incoming data but cannot connect to client

I am working on a simple server program and it works perfectly using 127.0.0.1 but when I set the IP to a client (100.2.132.128) who is running the client the server only can receive and am unable to send. The code is mostly based off MSDN. I used Wire shark to capture the traffic between Wire Shark.
The source code for the server attempting to send data to the client:
#pragma once
#pragma comment (lib, "Ws2_32.lib")
#define OUT_DEFAULT_BUFLEN 512
#define OUT_DEFAULT_PORT "20000"
bool Send(std::string arg, std::string IP){
if (arg.size() > 250){
return false;
}
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL, *ptr = NULL, hints;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(IP.c_str(), OUT_DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
return 1;
}
char *cstr = InAppendSizePacket(arg);
iResult = send(ConnectSocket, cstr, (int)strlen(cstr), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
char recvbuf[OUT_DEFAULT_BUFLEN];
int recvbuflen = OUT_DEFAULT_BUFLEN;
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0){
printf("Bytes received: %d\n", iResult);
if (recvbuf[0] == 'O' && recvbuf[1] == 'K'){
break;
}
}
else if (iResult == 0){
printf("Connection closed\n");
int debug = 0;
}
else{
printf("recv failed with error: %d\n", WSAGetLastError());
int debug = 0;
}
} while (iResult > 0);
std::cout << "The result is:" << recvbuf << std::endl;
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
The source code for the client waiting to accept data from the server is:
#pragma comment (lib, "Ws2_32.lib")
#define IN_DEFAULT_BUFLEN 512
#define IN_DEFAULT_PORT "20000"
unsigned __stdcall FTPAcceptSession(void *data){
int iSendResult;
char recvbuf[IN_DEFAULT_BUFLEN];
int recvbuflen = IN_DEFAULT_BUFLEN;
int iResult;
SOCKET ClientSocket = (SOCKET)data;
// Receive until the peer shuts down the connection
ClientQuarry NewPacket;
int err = getpeername(ClientSocket, (struct sockaddr *) &NewPacket.addr, &NewPacket.addr_len);
if (err != 0) {
// error, drop the packet.
closesocket(ClientSocket);
return 0;
}
std::vector<std::string> ToDump;
int amount = 0;
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
std::string temp = PrependSizePacket(recvbuf);
amount++;
ToDump.push_back(temp); //Add to the buffer.
}
else if (iResult == 0)
printf("Connection closing...\n");
else{
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
return 1;
}
char* LK = "OK";
iSendResult = send(ClientSocket, LK, iResult, 0);
if (iSendResult == SOCKET_ERROR || iSendResult == WSAEFAULT) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
} 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);
return 1;
}
closesocket(ClientSocket);
return 0;
}
DWORD WINAPI FileTransferProtocol(LPVOID lpParam){
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, IN_DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
for (;;){
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
break;
}
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &FTPAcceptSession, (void*)ClientSocket, 0, &threadID);
}
// 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();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
I added the program to firewall, open ports 20001 and 20000 for it. The server seems to timeout on the connect() request but I can't figure out why.