I want to write a client/server application, in which client and server can exchange messages.
Client site communication:
send
recv
send
recv
Server site communication:
recv
send
recv
send
However, I have a problem, because only one message is send/recv. After that, the socket is closed and further messages are not being sent. Whats wrong and how to fix this? Thank you.
Server code:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27501"
#define SIZE 1024
int SendAllToClient(SOCKET ClientSocket, char *buffer)
{
int iSendResult;
int total = 0, len = 1024;
int bytesleft = 1024;
while( total < len )
{
iSendResult = send( ClientSocket, buffer, 1024, NULL);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
total += iSendResult;
bytesleft -= iSendResult;
}
printf("Bytes sent: %d\n", iSendResult);
return total<len?- 1: 1;
}
char *ReadFromClient(SOCKET ConnectSocket)
{
int iResult;
char *buffer = new char[1024];
memset(buffer, 0, 1024);
do
{
iResult = recv(ConnectSocket, buffer, 1024, 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 );
return buffer;
}
int main(int argc , char *argv[])
{
WSADATA wsaData;
char *buffer;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int sessionID;
int iResult;
// Datagram d1,d2,d3;
// 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: %d\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;
}
printf("Server is listening on localhost:%s ...\n", DEFAULT_PORT);
// Accept a client socket
SOCKADDR_IN addr;
int addrlen = sizeof(addr);
ClientSocket = accept(ListenSocket, (SOCKADDR*)&addr, &addrlen);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
char *ip = inet_ntoa(addr.sin_addr);
int port = addr.sin_port;
printf("\nClient %s:%d connected to server\n", ip, port);
// No longer need server socket
closesocket(ListenSocket);
// 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;
}
//read
buffer = ReadFromClient(ClientSocket);
printf("FROM CLIENT: %s\n", buffer);
//send
memset(buffer, 0, 1024);
memcpy(buffer, "Hi client, how are you?", strlen("Hi client, how are you?"));
SendAllToClient(ClientSocket, buffer);
//read
//send
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
Client code:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27501"
#define SIZE 1024
int SendAllToServer(SOCKET ServerSocket, char *buffer)
{
int iSendResult;
int total = 0, len = 1024;
int bytesleft = 1024;
while( total < len )
{
iSendResult = send( ServerSocket, buffer, 1024, NULL);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ServerSocket);
WSACleanup();
return 1;
}
total += iSendResult;
bytesleft -= iSendResult;
}
printf("Bytes sent: %d\n", iSendResult);
return total<len?- 1: 1;
}
char *ReadFromServer(SOCKET ConnectSocket)
{
int iResult;
char *buffer = new char[1024];
memset(buffer, 0, 1024);
do {
iResult = recv(ConnectSocket, buffer, 1024, 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 );
return buffer;
}
int main(int argc , char *argv[])
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char* buffer;
int sessionID;
int iResult;
// Datagram d1,d2;
// 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("127.0.0.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: %d\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
buffer = new char[1024];
memset(buffer, 0, 1024);
memcpy(buffer, "Hi server", strlen("Hi server"));
SendAllToServer(ConnectSocket, buffer);
//read
memset(buffer, 0, 1024);
buffer = ReadFromServer(ConnectSocket);
printf("FROM SERVER: %s\n", buffer);
//send
//read
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
EDIT
Server
#include "data_types.h"
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define SIZE 1024
int SendAllToClient(SOCKET ClientSocket)
{
char *buffer = new char[SIZE];
int iSendResult;
memset(buffer, 0, SIZE);
int total = 0, len = SIZE;
int bytesleft = SIZE;
while( total < len )
{
iSendResult = send( ClientSocket, buffer + total, bytesleft, NULL);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
total += iSendResult;
bytesleft -= iSendResult;
}
printf("Bytes sent: %d\n", iSendResult);
delete buffer;
return total<len?- 1: 1;
}
char* ReadFromClient(SOCKET ClientSocket)
{
std::string data = "";
char *all = NULL;
char buffer[1];
int total = 0, len = SIZE;
int bytesleft = SIZE;
int iResult;
memset(buffer, 0, 1);
while(total < len)
{
if ((iResult = recv(ClientSocket, buffer, 1, 0)) == 0)
{
if (errno != 0)
{
// cleanup
closesocket(ClientSocket);
WSACleanup();
exit(1);
}
}
data = data + std::string(buffer);
total += iResult;
bytesleft -= iResult;
memset(buffer, 0, 1);
}
all = new char[data.length() + 1];
strcpy(all, data.c_str());
return all;
}
int main(int argc , char *argv[])
{
WSADATA wsaData;
char *buffer;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int sessionID;
int iResult;
// Datagram d1,d2,d3;
// 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: %d\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;
}
printf("Server is listening on localhost:%s ...\n", DEFAULT_PORT);
// Accept a client socket
SOCKADDR_IN addr;
int addrlen = sizeof(addr);
ClientSocket = accept(ListenSocket, (SOCKADDR*)&addr, &addrlen);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
char *ip = inet_ntoa(addr.sin_addr);
int port = addr.sin_port;
printf("\nClient %s:%d connected to server\n", ip, port);
// No longer need server socket
closesocket(ListenSocket);
// 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;
}
//read
buffer = new char[1024];
memset(buffer, 0, 1024);
buffer = ReadFromClient(ClientSocket);
printf("FROM CLIENT: %s\n", buffer);
//send
memset(buffer, 0, 1024);
memcpy(buffer, "Hi client, how are you?", strlen("Hi client, how are you?"));
// Send an initial buffer
iResult = send( ClientSocket, buffer, (int)strlen(buffer), 0 );
if (iResult == SOCKET_ERROR) {
wprintf(L"send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
//read
//send
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
Client
#include "data_types.h"
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define SIZE 1024
int SendAllToServer(SOCKET ClientSocket)
{
char *buffer = new char[SIZE];
memset(buffer, 0, SIZE);
int total = 0, len = SIZE;
int bytesleft = SIZE, iSendResult;
while( total < len )
{
iSendResult = send( ClientSocket, buffer + total, bytesleft, NULL);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
total += iSendResult;
bytesleft -= iSendResult;
}
printf("Bytes sent: %d\n", iSendResult);
delete buffer;
return total<len?- 1: 1;
}
char *ReadFromServer(SOCKET ClientSocket)
{
std::string data = "";
char *all = NULL;
char buffer[1];
int total = 0, len = SIZE;
int bytesleft = SIZE;
int iResult;
memset(buffer, 0, 1);
while(total < len)
{
if ((iResult = recv(ClientSocket, buffer, 1, 0)) == 0)
{
if (errno != 0)
{
// cleanup
closesocket(ClientSocket);
WSACleanup();
exit(1);
}
}
data = data + std::string(buffer);
total += iResult;
bytesleft -= iResult;
memset(buffer, 0, 1);
}
all = new char[data.length() + 1];
strcpy(all, data.c_str());
return all;
}
int main(int argc , char *argv[])
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char* buffer;
int sessionID;
int iResult;
// Datagram d1,d2;
// 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("127.0.0.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: %d\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
buffer = new char[1024];
memset(buffer, 0, 1024);
memcpy(buffer, "Hi server, how are you?", strlen("Hi server, how are you?"));
// Send an initial buffer
iResult = send( ConnectSocket, buffer, (int)strlen(buffer), 0 );
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
//read
memset(buffer, 0, 1024);
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, buffer, 1024, 0);
if ( iResult > 0 )
wprintf(L"Bytes received: %d\n", iResult);
else if ( iResult == 0 )
wprintf(L"Connection closed\n");
else
wprintf(L"recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
printf("FROM SERVER: %s\n", buffer);
//send
//read
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
First issue:
iSendResult = send( ClientSocket, buffer, 1024, NULL);
That 1024 should be bytesleft. If you've already read 512 bytes, you don't want to read more than another 512.
That buffer should be buffer + total. If you've already sent 512 bytes, you don't want to send the same 512 bytes again, you want to send the other 512 bytes.
Second issue:
Your ReadFromServer function is just completely broken and doesn't follow the right logic. It only returns on a fatal error and doesn't even try to read exactly 1,024 bytes. It just reads up to 1,024 bytes and then, no matter how many bytes it actually read, tries to read 1,024 bytes again -- and at the same address overwriting whatever part of the message it already read!
It should work just like the send function, first trying to receive 1,024 bytes and looping if it receives less than that until it has either received exactly 1,024 bytes or gotten a fatal error.
Third issue:
buffer = ReadFromServer(ConnectSocket);
printf("FROM SERVER: %s\n", buffer);
Don't do this. Suppose the server is malicious and sent you 1,024 bytes that are not a legal C-style string. Passing that to printf through %s could cause the client to crash or misbehave. Always treat data received from the network as untrusted and potentially hostile. Though your code will work without fixing this, one day doing this will bite you in some awful way and it's not a good habit to get into.
You should also delete[] the buffer when you're done with it. But why would you return a raw pointer anyway? You could return a std::string, a std::vector, or many other much better mechanisms that avoid the risk of leaks and make copies safe.
In fact you are closing the listen socket, so once there is an accepted connection it won't accept any more:
ClientSocket = accept(ListenSocket, (SOCKADDR*)&addr, &addrlen);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
char *ip = inet_ntoa(addr.sin_addr);
int port = addr.sin_port;
printf("\nClient %s:%d connected to server\n", ip, port);
// No longer need server socket
closesocket(ListenSocket);
Closing the listener prevents further connections.
Also, you are closing the client socket before handling it:
// 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;
}
//read
buffer = new char[1024];
memset(buffer, 0, 1024);
buffer = ReadFromClient(ClientSocket);
printf("FROM CLIENT: %s\n", buffer);
//send
memset(buffer, 0, 1024);
memcpy(buffer, "Hi client, how are you?", strlen("Hi client, how are you?"));
// Send an initial buffer
iResult = send( ClientSocket, buffer, (int)strlen(buffer), 0 );
If you want to send and receive several times, you should read/write in a loop. You are doing that only once (and doing it incorrectly): so only one message as you describe in your question.
Related
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());
If you try and run my script you can see that GetQueuedCompletionStatus not will block after second wsarecv call. I don't understand why this code won't work.
The code is a bit messy but quite simple so it should work.
server:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <thread>
#include <iostream>
using namespace std;
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
WSADATA wsaData;
int iResult;
HANDLE CompletionPort;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[200];
DWORD BytesSEND;
DWORD BytesRECV;
DWORD RecvBytes;
sockaddr_in local;
DWORD Flags;
int iSendResult;
void serverWorkerThread() {
OVERLAPPED lpol2;
DWORD Flags = 0;
DWORD BytesTransferred;
DWORD is = 0;
DWORD sentBytes;
bool kage = 0;
WSABUF wsabuf;
CHAR Buffer2[200];
while (true) {
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, &is, (LPOVERLAPPED*)& lpol2, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus() failed with error %d\n", GetLastError());
}
else
printf("GetQueuedCompletionStatus() is OK!\n");
cout << DataBuf.buf << endl;
cout << is;
DataBuf.len = 14;
ZeroMemory(&(Overlapped), sizeof(OVERLAPPED));
if (WSASend(ClientSocket, &DataBuf, 1, &sentBytes, 0,
NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
}
}
else
printf("WSASend() is OK!\n");
ZeroMemory(&(lpol2), sizeof(OVERLAPPED));
wsabuf.buf = Buffer2;
wsabuf.len = 200;
BytesTransferred = 0;
is = 0;
ZeroMemory(&(Overlapped), sizeof(OVERLAPPED));
Flags = 0;
if (WSARecv(ClientSocket, &wsabuf, 1, &RecvBytes, &Flags, &Overlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
}
}
else printf("WSARecv() is OK!\n");
}
}
int __cdecl main(void)
{
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
//Now we populate the sockaddr_in structure
local.sin_family = AF_INET; //Address family
local.sin_addr.s_addr = INADDR_ANY; //Wild card IP address
local.sin_port = htons((u_short)20248); //port to use
// Create a SOCKET for connecting to server
ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, (sockaddr*)& local, sizeof(local));
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
DataBuf.len = 2000;
DataBuf.buf = Buffer;
thread t1(serverWorkerThread);
t1.detach();
DWORD iss = 34543;
while (TRUE)
{
ClientSocket = WSAAccept(ListenSocket, NULL, NULL, NULL, 0);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
if (CreateIoCompletionPort((HANDLE)ClientSocket, CompletionPort, 43343, 0) == NULL)
{
printf("CreateIoCompletionPort() failed with error %d\n", GetLastError());
return 1;
}
else
printf("CreateIoCompletionPort() is OK!\n");
Flags = 0;
if (WSARecv(ClientSocket, &DataBuf, 1, &RecvBytes, &Flags, &Overlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return 1;
}
}
else printf("WSARecv() is OK!\n");
}
// 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;
}
client:
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
using namespace std;
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char** argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
SOCKADDR_IN ServerAddr;
// Server/receiver port to connect to
unsigned int Port = 20248;
//struct addrinfo* result = NULL,
// * ptr = NULL,
// hints;
const char* sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
cout << sendbuf << endl;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
// Create a SOCKET for connecting to server
ConnectSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 2;
}
// IPv4
ServerAddr.sin_family = AF_INET;
// Port no.
ServerAddr.sin_port = htons(Port);
// The IP address
ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR*)& ServerAddr, sizeof(ServerAddr));
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 3;
}
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 4;
}
// 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 5;
}
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 6;
}
// 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;
}
i found the problem:
the clients shoutdown the connetion which made the GetQueuedCompletionStatus keep running
This code contacts a server on my computer and sends packets to it (the server/client connection is fine). After the program loops for a number of times, it crashes with a SIGSEGV segmentation fault. I can't figure how to stop the crash from happening.
I just recently started working with clients/servers, and I retrieved the code from: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737591(v=vs.85).aspx
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x501
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <windows.h>
using namespace std;
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char **argv) {
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;
// 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 main(argc,argv);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Code:
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <string>
// link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFFER_LENGTH 512
class Client {
public:
Client(char* servername)
{
szServerName = servername;
ConnectSocket = INVALID_SOCKET;
}
bool Start() {
WSADATA wsaData;
// Initialize Winsock
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return false;
}
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
iResult = getaddrinfo(szServerName, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return false;
}
ptr = result;
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET)
{
printf("Error at socket(): %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return false;
}
// Connect to server
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET)
{
printf("Unable to connect to server!\n");
WSACleanup();
return false;
}
return true;
};
// Free the resouces
void Stop() {
int iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
printf("shutdown failed: %d\n", WSAGetLastError());
}
closesocket(ConnectSocket);
WSACleanup();
};
// Send message to server
bool Send(char* szMsg)
{
int iResult = send(ConnectSocket, szMsg, strlen(szMsg), 0);
if (iResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
Stop();
return false;
}
return true;
};
// Receive message from server
bool Recv()
{
char recvbuf[DEFAULT_BUFFER_LENGTH];
int iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0);
if (iResult > 0)
{
char msg[DEFAULT_BUFFER_LENGTH];
memset(&msg, 0, sizeof(msg));
strcpy_s(msg, recvbuf, iResult);
printf("Received: %s\n", msg);
return true;
}
return false;
}
private:
char* szServerName;
SOCKET ConnectSocket;
};
int main(int argc, CHAR* argv[])
{
std::string msg;
Client client("127.0.0.1");
if (!client.Start())
return 1;
while(true)
{
std::cout << "Send: ";
std::getline(std::cin, msg);
// Close the connection when user enter "close"
if (msg.compare("close") == 0)
{
break;
}
client.Send((char*)msg.c_str());
client.Recv();
}
client.Stop();
getchar();
return 0;
}
and
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
// link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFFER_LENGTH 512
int main() {
WSADATA wsaData;
// Initialize Winsock
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
struct addrinfo *result = NULL,
hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET; // Internet address family is unspecified so that either an IPv6 or IPv4 address can be returned
hints.ai_socktype = SOCK_STREAM; // Requests the socket type to be a stream socket for the TCP protocol
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the local address and port to be used by the server
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}
SOCKET ListenSocket = INVALID_SOCKET;
// Create a SOCKET for the server to listen for client connections
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
printf("Error at socket(): %d\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: %d", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
// To listen on a socket
if ( listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)
{
printf("listen failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
SOCKET ClientSocket;
ClientSocket = INVALID_SOCKET;
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
char recvbuf[DEFAULT_BUFFER_LENGTH];
int iSendResult;
// reveice until the client shutdown the connection
do {
iResult = recv(ClientSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0);
if (iResult > 0)
{
char msg[DEFAULT_BUFFER_LENGTH];
memset(&msg, 0, sizeof(msg));
strcpy_s(msg, recvbuf, iResult);
printf("Received: %s\n", msg);
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %ld\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closed\n");
else
{
printf("recv failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
//return 1;
}
} while (iResult > 0);
// Free the resouces
closesocket(ListenSocket);
WSACleanup();
getchar();
return 0;
}
Errors:
error C2664: 'errno_t strcpy_s(char *,rsize_t,const char *)' : cannot
convert parameter 2 from 'char [512]' to 'rsize_t'
error C2664: 'errno_t strcpy_s(char *,rsize_t,const char *)' : cannot
convert parameter 2 from 'char [512]' to 'rsize_t'
IntelliSense: no instance of overloaded function "strcpy_s" matches
the argument list
argument types are: (char [512], char [512], int)
I have been trying to fix this problem. Please help.
New code:
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
// link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFFER_LENGTH 128
int main() {
WSADATA wsaData;
// Initialize Winsock
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
struct addrinfo *result = NULL,
hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET; // Internet address family is unspecified so that either an IPv6 or IPv4 address can be returned
hints.ai_socktype = SOCK_STREAM; // Requests the socket type to be a stream socket for the TCP protocol
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the local address and port to be used by the server
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}
SOCKET ListenSocket = INVALID_SOCKET;
// Create a SOCKET for the server to listen for client connections
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
printf("Error at socket(): %d\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: %d", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
// To listen on a socket
if ( listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)
{
printf("listen failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
SOCKET ClientSocket;
ClientSocket = INVALID_SOCKET;
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
char recvbuf[DEFAULT_BUFFER_LENGTH];
int iSendResult;
// reveice until the client shutdown the connection
do {
iResult = recv(ClientSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0);
if (iResult > 0)
{
char msg[DEFAULT_BUFFER_LENGTH];
memset(&msg, 0, sizeof(msg));
strcpy_s(msg, iResult, recvbuf);
printf("Received: %s\n", msg);
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %ld\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closed\n");
else
{
printf("recv failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
//return 1;
}
} while (iResult > 0);
// Free the resouces
closesocket(ListenSocket);
WSACleanup();
getchar();
return 0;
}
New error:
http://i.stack.imgur.com/55IUF.png
You have the parameters in the wrong order.
errno_t strcpy_s(char *dest, rsize_t size, const char *src);
You put the src in the size param and the size in the src param.
My question is about this previous question (unfortunely, the answer doesn't work for me): https://stackoverflow.com/questions/20314524/c-opencv-image-sending-through-socket
After get the image, the code shows only a grey picture. Am I doing the correct image handling when sending and receive the image?
Sender and receiver codes:
Image sender:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define IMG_BUFLEN 1243897
#define DEFAULT_PORT "27015"
using namespace std;
using namespace cv;
int main(void)
{
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];
unsigned char * imgbuf;
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;
}
// 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("SERVER - bytes: %d\n", iResult);
//char * temp = (char *) malloc(9); memcpy(temp,recvbuf,8);
if (strcmp(recvbuf, "ASK"))
{
int retTamImg;
Mat captureFrame;
int imgSize = 0;
VideoCapture captureDevice;
captureDevice.open(0);
if(!captureDevice.isOpened() )
{
printf("Nao pode ler o video");
getchar();
}
captureDevice>>captureFrame;
//---------------- SEND IMAGE ----------------//
if (captureFrame.data != NULL)
{
retTamImg = captureFrame.total() * captureFrame.elemSize();
iSendResult = send( ClientSocket, (const char *) captureFrame.data, retTamImg, 0 );
if (iSendResult == SOCKET_ERROR) {
printf("resposta de pedido de face falhou. erro: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
else
printf("resposta de pedido de face enviada com suceso. Bytes: %d\n", iSendResult);
}
//FECHA CAMERA
captureDevice.release();
}
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
getchar();
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();
getchar();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
Image receiver:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define IMG_BUFLEN 1243897
#define DEFAULT_PORT "27015"
using namespace std;
using namespace cv;
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char sendbuf [DEFAULT_BUFLEN];
char recvbuf[DEFAULT_BUFLEN];
char * imgbuf;
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);
getchar();
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("127.0.0.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();
getchar();
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();
getchar();
return 1;
}
//----------------- ASK FOR THE IMAGE ----------------------//
strncpy(sendbuf, "ASK", 8);
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send ASK FACE failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getchar();
return 1;
}
printf("ASK FACE SENT Bytes Sent: %ld\n", iResult);
//----------------- GET THE IMAGE ----------------------//
Mat img = Mat::zeros( 480,640, CV_8UC3);
int imgSize = (int) (img.total()*img.elemSize());
char * sockData;
sockData = (char *) malloc (sizeof(char) * imgSize + 1);
for (int i = 0; i < imgSize; i += iResult)
{
iResult = recv(ConnectSocket, sockData +i, imgSize - i, 0);
if ( iResult > 0 )
printf("CLIENTE - retorno do ASK FACE (%d/%d)- Bytes received: %d\n", i, imgSize, iResult);
else if ( iResult == 0 )
printf("CLIENTE - retorno do ASK FACE - Connection closed\n");
else
printf("CLIENTE - retorno do ASK FACE - error: %d\n", WSAGetLastError());
}
// Assign pixel value to img
int iptr=0;
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
img.at<cv::Vec3b>(i,j) = Vec3b(sockData[iptr+ 0],sockData[iptr+1],sockData[iptr+2]);
iptr=iptr+3;
}
}
namedWindow("outputCapture", 1);
imshow("outputCapture", img);
// imwrite("C:\\Users\\USUARIO\\Documents\\VISAO\\servidor_imagens_cam\\imagem_salva.jpg",img);
// 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;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
getchar();
return 0;
}
After some time here with your code, i finally found the error. You have to use waitkey() and not getchar(). Besides this, the program it's running fine.