A very simple server that's show how to apply the windows CreateThread function, follows the normal procedure in creating a server,
But the only change was that once its within the while loop, continuously accept incoming connection, then create a thread for the every connection it makes.
The CreateThread takes 6 arguments, but assigned only the function you want to run within that thread, argument of that function, and one optional argument i added for the thread id.
The function has to be separately implemented and it always takes LPVOID paramenter, VOID POINTER, i believe. And can be casted when used.
#define _WIN32_WINNT 0x501
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT "4444"
#define BUFFER 1024
using namespace std;
DWORD WINAPI recvNsend(LPVOID lpParam);
struct addrinfo *result, *ptr, hints;
SOCKET servSocket;
SOCKET clntSocket;
void callWsDll()
{
WSADATA wsadata;
int iResult;
iResult = WSAStartup(MAKEWORD(2,2), &wsadata);
if(iResult != 0)
{
cout << "WSAStartup or Calling the socket DLL fail" << endl;
}
}
int createNconnect()
{
int iResult;
DWORD thread;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = getaddrinfo(NULL, PORT, &hints, &result);
if(iResult != 0)
{
cout << "getaddrinfo failed " << endl;
WSACleanup();
}
ptr = result;
servSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if(servSocket == INVALID_SOCKET)
{
cout << "socket creation failed " << WSAGetLastError() << endl;
freeaddrinfo(result);
WSACleanup();
return 1;
}
iResult = bind(servSocket, ptr->ai_addr, ptr->ai_addrlen);
if(iResult == SOCKET_ERROR)
{
cout << "socket binding failed " << WSAGetLastError() << endl;
freeaddrinfo(result);
WSACleanup();
return 1;
}
freeaddrinfo(ptr);
freeaddrinfo(result);
iResult = listen(servSocket, SOMAXCONN);
if(iResult == SOCKET_ERROR)
{
cout << "listening failed " << WSAGetLastError() << endl;
closesocket(servSocket);
WSACleanup();
return 1;
}
while(true)
{
clntSocket = accept(servSocket, NULL, NULL);
if(clntSocket == INVALID_SOCKET)
{
cout << "accepting clients failed " << WSAGetLastError() <<endl;
closesocket(servSocket);
WSACleanup();
return 1;
}
CreateThread(NULL, 0, recvNsend, (LPVOID)clntSocket, 0, &thread);
cout << thread << endl;
}
closesocket(servSocket);
return iResult;
}
DWORD WINAPI recvNsend(LPVOID lpParam)
{
int iResult;
int iSresult;
char rcvbuffer[BUFFER];
SOCKET rsclientSocket = (SOCKET)lpParam;
do{
iResult = recv(rsclientSocket, rcvbuffer, BUFFER, 0);
if(iResult > 0)
{
cout << "Bytes recieved " << iResult << endl;
iSresult = send(rsclientSocket, rcvbuffer, iResult, 0);
if(iSresult == SOCKET_ERROR)
{
cout << "send failed" << WSAGetLastError() << endl;
closesocket(rsclientSocket);
WSACleanup();
return 1;
}
cout << "Bytes sent " << iSresult << endl;
}
else if(iResult == 0)
{
cout << "Connection closed ...." << endl;
}
else
{
cout << "Recieving message failed " << WSAGetLastError() << endl;
closesocket(rsclientSocket);
WSACleanup();
return 1;
}
}while(iResult > 0);
return 0;
}
int shutdownSocket(SOCKET &anysock)
{
int iResult;
iResult = shutdown(anysock, SD_SEND);
if(iResult == SOCKET_ERROR)
{
cout << "shutdown failed" << WSAGetLastError() << endl;
closesocket(anysock);
WSACleanup();
return 1;
}
closesocket(anysock);
WSACleanup();
return 0;
}
- Initialization of the DLL
- create socket
- bind the socket
- listen for an incoming connection
But the only change was that once its within the while loop, continuously accept incoming connection, then create a thread for the every connection it makes.
The CreateThread takes 6 arguments, but assigned only the function you want to run within that thread, argument of that function, and one optional argument i added for the thread id.
- recvNsend - Function i want to run with in the thread
- (LPVOID)clntSocket - parameter it takes in, that is the accecpted client,
The function has to be separately implemented and it always takes LPVOID paramenter, VOID POINTER, i believe. And can be casted when used.
#define _WIN32_WINNT 0x501
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT "4444"
#define BUFFER 1024
using namespace std;
DWORD WINAPI recvNsend(LPVOID lpParam);
struct addrinfo *result, *ptr, hints;
SOCKET servSocket;
SOCKET clntSocket;
void callWsDll()
{
WSADATA wsadata;
int iResult;
iResult = WSAStartup(MAKEWORD(2,2), &wsadata);
if(iResult != 0)
{
cout << "WSAStartup or Calling the socket DLL fail" << endl;
}
}
int createNconnect()
{
int iResult;
DWORD thread;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = getaddrinfo(NULL, PORT, &hints, &result);
if(iResult != 0)
{
cout << "getaddrinfo failed " << endl;
WSACleanup();
}
ptr = result;
servSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if(servSocket == INVALID_SOCKET)
{
cout << "socket creation failed " << WSAGetLastError() << endl;
freeaddrinfo(result);
WSACleanup();
return 1;
}
iResult = bind(servSocket, ptr->ai_addr, ptr->ai_addrlen);
if(iResult == SOCKET_ERROR)
{
cout << "socket binding failed " << WSAGetLastError() << endl;
freeaddrinfo(result);
WSACleanup();
return 1;
}
freeaddrinfo(ptr);
freeaddrinfo(result);
iResult = listen(servSocket, SOMAXCONN);
if(iResult == SOCKET_ERROR)
{
cout << "listening failed " << WSAGetLastError() << endl;
closesocket(servSocket);
WSACleanup();
return 1;
}
while(true)
{
clntSocket = accept(servSocket, NULL, NULL);
if(clntSocket == INVALID_SOCKET)
{
cout << "accepting clients failed " << WSAGetLastError() <<endl;
closesocket(servSocket);
WSACleanup();
return 1;
}
CreateThread(NULL, 0, recvNsend, (LPVOID)clntSocket, 0, &thread);
cout << thread << endl;
}
closesocket(servSocket);
return iResult;
}
DWORD WINAPI recvNsend(LPVOID lpParam)
{
int iResult;
int iSresult;
char rcvbuffer[BUFFER];
SOCKET rsclientSocket = (SOCKET)lpParam;
do{
iResult = recv(rsclientSocket, rcvbuffer, BUFFER, 0);
if(iResult > 0)
{
cout << "Bytes recieved " << iResult << endl;
iSresult = send(rsclientSocket, rcvbuffer, iResult, 0);
if(iSresult == SOCKET_ERROR)
{
cout << "send failed" << WSAGetLastError() << endl;
closesocket(rsclientSocket);
WSACleanup();
return 1;
}
cout << "Bytes sent " << iSresult << endl;
}
else if(iResult == 0)
{
cout << "Connection closed ...." << endl;
}
else
{
cout << "Recieving message failed " << WSAGetLastError() << endl;
closesocket(rsclientSocket);
WSACleanup();
return 1;
}
}while(iResult > 0);
return 0;
}
int shutdownSocket(SOCKET &anysock)
{
int iResult;
iResult = shutdown(anysock, SD_SEND);
if(iResult == SOCKET_ERROR)
{
cout << "shutdown failed" << WSAGetLastError() << endl;
closesocket(anysock);
WSACleanup();
return 1;
}
closesocket(anysock);
WSACleanup();
return 0;
}
No comments:
Post a Comment