Windows message loop and server loop - c++

I made a window using the Win32 API and it needs to enter a message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
How do I create a socket server and start receiving clients, if my main thread is processing UI messages?
I tried putting all of the server code in a thread using CreateThread() from WinMain(), but it just crashes with an error:
Exception thrown at 0x00000000 in test.exe: 0xC0000005: Access violation executing location 0x00000000.
Here is the thread code:
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
// Initialize Winsock
WSADATA wsaData;
auto iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return EXIT_FAILURE;
}
addrinfo hints;
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
PADDRINFOA pAddrInfo = nullptr;
iResult = getaddrinfo(nullptr, PORT, &hints, &pAddrInfo);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return EXIT_FAILURE;
}
while (true) {
// Create a SOCKET for connecting to server
auto ListenSocket = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, pAddrInfo->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(pAddrInfo);
WSACleanup();
return EXIT_FAILURE;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, pAddrInfo->ai_addr, static_cast<int>(pAddrInfo->ai_addrlen));
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(pAddrInfo);
closesocket(ListenSocket);
WSACleanup();
return EXIT_FAILURE;
}
freeaddrinfo(pAddrInfo);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return EXIT_FAILURE;
}
// Accept a client socket
auto ClientSocket = accept(ListenSocket, nullptr, nullptr);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return EXIT_FAILURE;
}
// No longer need server socket
closesocket(ListenSocket);
// Receive until the peer shuts down the connection
for (;;)
{
char recvbuf[1] = { 0 };
auto cbLen = recv(ClientSocket, recvbuf, sizeof(recvbuf), 0);
if (cbLen > 0) {
if (recvbuf[0] == 0xDA)
{
Hide();
}
continue;
}
else if (cbLen == 0) {
printf("Connection closing...\n");
break;
}
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return EXIT_FAILURE;
}
}
// shutdown receive operations since we're done
iResult = shutdown(ClientSocket, SD_RECEIVE);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return EXIT_FAILURE;
}
// cleanup
closesocket(ClientSocket);
}
WSACleanup();
return 0;
}

This is a very confusing question as it asks one question in the title, but the content addresses a different problem (threads crashing).
To address the primary question: Microsoft did add a way to handle socket communications in a GUI thread friendly way: WSAAsyncSelect. This will send socket events as messages to your applications message queue - typically an invisible window is created to handle the messages.

Related

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?

C++ multi threaded server

I'm working on a server that just connects a client and sends back what they type. So far it works well, but I want to make it multi-threaded so I can connect more clients, so they can "Talk." Can you guys refer me to any source code that I can look over to make some adjustments to my own code? Thanks. I would also like this to work on different networks, and I am not sure how to do this so some source code to that as well would work. Also I'm in eighth grade and haven't had a lot of experience so a well-explained answer would be appreciated.
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));
strncpy(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;
}
There are dozens of ways how to implement this solution.
First of all, it is better to design what approach is preferable for your educational purposes.
Considering network programming:
One of the best guides for network programming I can recommend is Beej's Guide.
Considering server-side architecture:
I would like to recommend C++ Concurrency in Action: Practical Multithreading by Anthony Williams for further reading.
Before you, a whole sea of possibilities - go for it!
Ps: considering general questions like this
It is better to look for an answer to such questions in softwareengineering forum.

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 :|

How can I Always open server?

I have code (my c++ socket server) but I don't know How can I always open. My server will close. when It already send to client It will close itself. But I want it to wait others client and never closed. How can I do it ? Oh I use multi-threaded too.
please,Help me.
and here is my code
int main(void)
{
HANDLE hThread[3];
DWORD dwID[3];
DWORD dwRetVal = 0;
hThread[0] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadTwo,NULL,0,&dwID[0]);
dwRetVal = WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
return 0;
}
long WINAPI ThreadTwo(long lParam)
{
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET,
ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
hints;
char recvbuf[DEFAULT_BUFLEN];
int iResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN;
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;
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;
}
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("Waiting for client\n");
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Client acctped.\n");
closesocket(ListenSocket);
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
recvbuf[iResult] = '\0';
printf(recvbuf);
char* testsend = "222 333\n444 555\n666 777" ;
iSendResult = send( ClientSocket, testsend , strlen(testsend)+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);
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
system("pause");
closesocket(ClientSocket);
WSACleanup();
return 0;
}
thank again.
You have to use a loop for that :)
Basically, the server main code must be in a loop, that will go forever ... while you do not stop it.
you should have :
// That's close to pseudo code :)
while(notStoppedByMaster)
{
// [...]
ClientSocket = accept(ListenSocket, NULL, NULL);
handleRequest(ClientSocket);
}
// close the listen socket here
The handleRequest should handle the request in another thread. Be attentive to synchronization :)
my2c
Firstly, it looks like you are creating a console application. If I were you I would create a WIN32 application instead. This means you'll have a GUI but more importantly, a message loop. The message loop allows you to use Asynchronous sockets, it takes a little more understanding but it gives much better and cleaner results.
Read about WSAAsyncSelect:
http://msdn.microsoft.com/en-us/library/ms741540%28VS.85%29.aspx
Also read socket tutorial:
http://msdn.microsoft.com/en-us/library/ms738545%28v=VS.85%29.aspx
Secondly, if you HAVE to use synchronous (blocking) sockets, yes you'll have to be running each on its own thread. You Need to have a loop in which you wait for connections, and then have client sockets like you did, being assigned from your accept(). Then let the client sockets run on their own thread.
Also you are closing your listensocket for some reason in the middle of the code.