Udp_client_server_using Multi-threading - c++

I implented basic udp client server application using multi threading but actually the thread is not invoking...can any body help me..
class uu_FrameWorkSocket
{
protected:
struct sockaddr_in ModuleMySocketAddress;
uu_int32 ModuleHostPortK;
uu_char* ModuleHostNameK;
uu_int32 ModuleSockFlagK;
uu_int32* ModuleSockOptValueP;
public:
uu_void uu_ModuleInitSocket(uu_int32,uu_int32);
uu_void uu_ModuleSetSocketOptions(uu_int32);
uu_void SetHostName(uu_char* );
uu_void SetPortNumber(uu_int32 );
uu_void uu_ModuleCloseSocket(uu_int32 );
uu_FrameWorkSocket(){
ModuleHostPortK = 3232;
ModuleHostNameK = (uu_char*) malloc(20);
strcpy(ModuleHostNameK,"127.0.0.1");
}
};
uu_void uu_FrameWorkSocket :: SetHostName(uu_char *psHostName){
ModuleHostNameK = (uu_char*) malloc(20);
strcpy(ModuleHostNameK,psHostName);
}
uu_void uu_FrameWorkSocket :: SetPortNumber(uu_int32 iPortNumber){
ModuleHostPortK=iPortNumber;
}
uu_void uu_FrameWorkSocket :: uu_ModuleCloseSocket(uu_int32 iSocketfd){
close(iSocketfd);
}
uu_void uu_FrameWorkSocket :: uu_ModuleInitSocket(uu_int32 iTypeFamily,uu_int32 iTypeProtocol){
if(iTypeFamily == UU_PROJECT_MODULE_IPV4)
{
if(iTypeProtocol == UU_PROJECT_MODULE_TCP)
ModuleSockFlagK = socket(AF_INET, SOCK_STREAM, 0);
else
ModuleSockFlagK = socket(AF_INET, SOCK_DGRAM, 0);
}
else
{
if(iTypeProtocol == UU_PROJECT_MODULE_TCP)
ModuleSockFlagK = socket(AF_INET6, SOCK_STREAM, 0);
else
ModuleSockFlagK = socket(AF_INET6, SOCK_DGRAM, 0);
}
if (ModuleSockFlagK == -1){
printf("Error while initializing socket.\n");
exit(0);
}
}
uu_void uu_FrameWorkSocket :: uu_ModuleSetSocketOptions(uu_int32 iTypeFamily){
ModuleSockOptValueP = (uu_int32*)malloc(sizeof(uu_int32));
*ModuleSockOptValueP = 1;
if( (setsockopt(ModuleSockFlagK, SOL_SOCKET, SO_REUSEADDR, (uu_char*)ModuleSockOptValueP, sizeof(uu_int32)) == -1 ) ){
printf("Error while setting socket options.\n");
free(ModuleSockOptValueP);
exit(0);
}
free(ModuleSockOptValueP);
if(iTypeFamily == UU_PROJECT_MODULE_IPV4)
ModuleMySocketAddress.sin_family = AF_INET ;
else
ModuleMySocketAddress.sin_family = AF_INET6 ;
ModuleMySocketAddress.sin_port = htons(ModuleHostPortK);
memset(&(ModuleMySocketAddress.sin_zero), 0, 8);
ModuleMySocketAddress.sin_addr.s_addr = inet_addr(ModuleHostNameK);
}
class uu_ProjectModuleUdp : public uu_FrameWorkSocket
{
protected:
socklen_t ModuleMySockAddrLength;
uu_int32* ModuleSockConnFlag;
sockaddr_in ModuleIpSockAddr;
pthread_t ModuleThreadId;
public:
struct Request{
sockaddr_in ModuleClientSockAddr;
uu_int32 ModuleClientSocket;
};
uu_void ModuleUdpBind(){
if( bind( ModuleSockFlagK, (sockaddr*)&ModuleMySocketAddress, sizeof(ModuleMySocketAddress)) == -1 ){
fprintf(stderr,"Error while binding to socket:%d\n",errno);
exit(0);
}
}
uu_void ModuleUdpAccept(){
ModuleMySockAddrLength = sizeof(sockaddr_in);
uu_char Msg[100];
uu_int32 N;
struct Request ModuleRequestStructure;
while(true){
if(( N= recvfrom( ModuleSockFlagK,Msg,100,0, (sockaddr*)&ModuleIpSockAddr, &ModuleMySockAddrLength))!= -1){
printf("==\nReceived connection from %s\n",inet_ntoa(ModuleIpSockAddr.sin_addr));
printf("Received message: %s \n",Msg);
sendto( ModuleSockFlagK,Msg,N,0, (sockaddr*)&ModuleIpSockAddr, ModuleMySockAddrLength);
ModuleRequestStructure.ModuleClientSockAddr=ModuleIpSockAddr;
ModuleRequestStructure.ModuleClientSocket=ModuleSockFlagK;
pthread_create(&ModuleThreadId,0,&ModuleUdpSocketHandler, (uu_void*)&ModuleRequestStructure );
pthread_detach(ModuleThreadId);
}
else{
fprintf(stderr, "Error accepting... %d\n", errno);
}
}
}
static uu_void* ModuleUdpSocketHandler(uu_void* ModuleRequestStruct){
Request *ModuleRequest=(Request *)ModuleRequestStruct;
uu_int32 iClientSocket=ModuleRequest->ModuleClientSocket;
sockaddr_in ClientSockaddr=ModuleRequest->ModuleClientSockAddr;
socklen_t ModuleMySockAddrLength = sizeof(sockaddr_in);
uu_char acBuffer[1024];
uu_int32 iBufferLen = 1024;
uu_int32 iByteCount;
while(true){
memset(acBuffer, '\0', iBufferLen);
if((iByteCount = recvfrom(iClientSocket,acBuffer,iBufferLen,0,(sockaddr*)&ClientSockaddr,&ModuleMySockAddrLength))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
exit(0);
}
printf("Received bytes: %d\nReceived string: %s \n", iByteCount, acBuffer);
if((iByteCount = sendto(iClientSocket, acBuffer, strlen(acBuffer), 0,(sockaddr*)&ClientSockaddr,ModuleMySockAddrLength))== -1){
fprintf(stderr, "Error sending data %d\n", errno);
exit(0);
}
printf("Sent bytes %d\n", iByteCount);
}
}
uu_void ModuleUdpAfterConn(){
uu_char acBuffer[1024];
uu_int32 iByteCount;
uu_int32 iBufferLen=0;
ModuleMySockAddrLength = sizeof(sockaddr_in);
iBufferLen = 1024;
while(true){
memset(acBuffer, '\0', iBufferLen);
printf("Enter some text to send to the server (press enter):\n");
fgets(acBuffer, 1024, stdin);
acBuffer[strlen(acBuffer)-1]='\0';
if( (iByteCount=sendto(ModuleSockFlagK, acBuffer, strlen(acBuffer),0,(sockaddr*)&ModuleMySocketAddress,ModuleMySockAddrLength))== -1){
fprintf(stderr, "Error sending data %d\n", errno);
exit(0);
}
printf("Sent bytes %d\n", iByteCount);
if((iByteCount = recvfrom(ModuleSockFlagK, acBuffer, iBufferLen, 0,NULL,NULL))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
exit(0);
}
printf("Recieved bytes: %d\nReceived string: \"%s\"\n", iByteCount, acBuffer);
}
close(ModuleSockFlagK);
}
};
int main(int argc, char **argv){
if(strcmp(argv[1],"udp")==0){
if(strcmp(argv[2],"server")==0){
printf("This is UDP Server");
uu_ProjectModuleUdp server;
server.SetPortNumber(6745);
server.uu_ModuleInitSocket(UU_PROJECT_MODULE_IPV4,UU_PROJECT_MODULE_UDP);
server.uu_ModuleSetSocketOptions(UU_PROJECT_MODULE_IPV4);
server.ModuleUdpBind();
server.ModuleUdpAccept();
}
else if(strcmp(argv[2],"client")==0){
printf("This is UDP Client");
uu_ProjectModuleUdp client;
client.SetPortNumber(6745);
client.uu_ModuleInitSocket(UU_PROJECT_MODULE_IPV4,UU_PROJECT_MODULE_UDP);
client.uu_ModuleSetSocketOptions(UU_PROJECT_MODULE_IPV4);
client.ModuleUdpAfterConn();
}
}
else
printf("Wrong/Missing Arguments\n");
return 0;
}
Here for each client a thread has to be invoked but it is not invoking..

What is probably happening is that your thread crashes. The reason would be undefined behavior when you try to access the ModuleRequest pointer, as it points to a local variable inside ModuleUdpAccept.
When ModuleUdpAccept returns, that pointer is no longer pointing to valid memory, and you get undefined behavior, which may (or may not) cause the thread to crash.

Related

C++ - send the file periodically through socket

I'm a new comer in this stackoverflow.
I successfully sent a file.txt and received it . And I want to send the file through a socket periodically and receive it periodically, too. This is a server client program. Client should send the data and server should receive it with an interval time.
Anyone know how to do this? I used this way:
need to call a function at periodic time intervals in c++
Problem is the file is not sent.
Here is my client code :
void Inwinsock(){
WSAStartup(MAKEWORD(2,2), &winsock);
if (LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2 ) {
WSACleanup();
}
}
void ClientSock() {
clientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(6091);
}
int _tmain(int argc, _TCHAR* argv[])
{
Inwinsock();
ClientSock();
start:
if (connect(clientSock, (sockaddr*)&addr, sizeof(addr)) < 0 ) {
Sleep(5000);
goto start;
}
printf("Socket Connected ......... \n");
FILE *File;
char *Buffer;
unsigned long Size;
File = fopen("B:\Filesend.txt","rb");
if(!File){
printf("", WSAGetLastError());
goto END;
}
printf("File open ok ! \n");
fseek(File,0,SEEK_END);
Size = ftell(File);
fseek(File,0,SEEK_SET);
printf("file size succeed...\n");
Buffer = (char*) malloc (Size+1);
fread(Buffer,Size,1,File);
char cisi[10];
sprintf(cisi, "%i", Size);
fclose(File);
printf("sending data....\n");
send(clientSock,cisi,10,0); //file size sent
send(clientSock,Buffer,Size,0); // File Binary sent
free(Buffer);
printf("sending finished....\n");
END:
closesocket(clientSock);
WSACleanup();
getchar();
return 0;
system("PAUSE");
}
and here are my server code :
void iniSocket() {
WSAStartup(MAKEWORD(2,2), &winsock);
if (LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2) {
WSACleanup();
}
}
void opSock(){
servSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&addr , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(6091);
bind(servSocket, (sockaddr*)&addr, sizeof(addr));
}
void sockList(){
if (listen(servSocket, 5) == SOCKET_ERROR ) {
printf("listen error %d\n", WSAGetLastError());
}else
{
printf("listen succeed....\n");
}
}
void receive() {
if(recv(ClientAcc,Filesize,10,0)){
Size = atoi((const char*)Filesize);
printf("File size : %d\n",Size);
}
Buffer = (char*)malloc(Size + 1);
int file_dit, total_file = 0 ;
while(total_file < Size)
{
ZeroMemory(Buffer, Size);
if((file_dit = recv(ClientAcc,Buffer,Size,0)) < 0)
{
goto END;
}
else
{
total_file += file_dit;
File = fopen("fileReceived.txt", "wb");
fwrite((const char*)Buffer,1,file_dit,File);
fclose(File);
Sleep(1000);
}
END:
printf("File received \n");
free(Buffer);
closesocket(ClientAcc);
WSACleanup();
getchar();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
while(1)
{
iniSocket();
opSock();
sockList();
if (ClientAcc = accept(servSocket, (sockaddr*)&incommingAddress, &addresslen))
{
char *ClientIP = inet_ntoa(incommingAddress.sin_addr);
int ClientPort = ntohs (incommingAddress.sin_port);
printf("Client connected ....\n" );
printf("IP : %s:%d\n ", ClientIP, ClientPort);
receive();
}
}
return 0;
system("PAUSE");
}
For the periodic part, you could take everything between the start: and END: labels, and put it in a new function, say, sendMyFile();
Then in the client's _tmain(), between the start: and END: labels,
while (1)
{
sendMyFile();
Sleep( 30000 ); // The interval is 30,000.
}
There are certainly better, more sophisticated ways to do something periodically, but this is a good, simple, educational approach.

Improve server to deal with multiple clients

I'm trying to create a server that talks with 2 clients, 1 in each time. After the talking with one client, the server sends a message to both clients.
I found a basic code of a server, and I tried to upgrade it to accept multiple number of connections, and I saw 2 ways of it : threads, or doing array of sockets, but I couldn't understand it.
Can someone explain me how to use threads and give examples please?
This is the code :
int main()
{
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2, 2), &WsaDat) != 0)
{
std::cout << "WSA Initialization failed!\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Socket == INVALID_SOCKET)
{
std::cout << "Socket creation failed.\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
SOCKADDR_IN serverInf;
serverInf.sin_family = AF_INET;
serverInf.sin_addr.s_addr = INADDR_ANY;
serverInf.sin_port = htons(8888);
if (bind(Socket, (SOCKADDR*)(&serverInf), sizeof(serverInf)) == SOCKET_ERROR)
{
std::cout << "Unable to bind socket!\r\n";
WSACleanup();
system("PAUSE");
return 0;
}
listen(Socket, 1);
SOCKET TempSock = SOCKET_ERROR;
while (TempSock == SOCKET_ERROR)
{
std::cout << "Waiting for incoming connections...\r\n";
TempSock = accept(Socket, NULL, NULL);
}
// If iMode!=0, non-blocking mode is enabled.
u_long iMode = 1;
ioctlsocket(Socket, FIONBIO, &iMode);
Socket = TempSock;
std::cout << "Client connected!\r\n\r\n";
// Main loop
for (;;)
{
char *szMessage = "Welcome to the server!\r\n";
send(Socket, szMessage, strlen(szMessage), 0);
int nError = WSAGetLastError();
if (nError != WSAEWOULDBLOCK&&nError != 0)
{
std::cout << "Winsock error code: " << nError << "\r\n";
std::cout << "Client disconnected!\r\n";
// Shutdown our socket
shutdown(Socket, SD_SEND);
// Close our socket entirely
closesocket(Socket);
break;
}
Sleep(1000);
}
WSACleanup();
system("PAUSE");
return 0;
}
To do so you need one server socket and a clientsocket array like this:
SERVER:
ACCEPT:
int clientsock[2];
minsocks = 0;
numsocks = 2;
while(minsock < numsocks)
{
clientsock[minsock] = accept(serversock,
(struct sockaddr *) &clientaddr,
(socklen_t *)&clientaddrlen);
minsock++;
}
RECIEVE:
char message[6];
int data;
int limit = 6;
for(int i = 0; i < NUMSOCK; i++)
{
int in = recv(clientsock[i], &message[index], limit, 0);
if(in > 0)
{
index += in;
limit -= in;
}
else if ( in == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
}
This should be a good beginning for you to start with.
Threads - C version
pthread_t sniffer_thread;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
while(in != 0)
{
int in = recv(socket_desc, &client_message[index], limit, 0);
if(in > 0)
{
index += in;
limit -= in;
}
else
printf("recv failed: %d\n", WSAGetLastError());
}
//Free the socket pointer
free(socket_desc);
return 0;
}

creating daemon processing from server socket

I have one socket, which act as server while executed and response some results.
First I compile it: g++ -o a daemon.cpp dictionary.cpp -lpthread c++11
then execute : ./a
Now it will listen for the request on some port.
I want that one I create the object file a, it should not manually executed. Rather work as daemon file, which continously listen for the request.
I saw using fork() id something can be done. But I could not correct place in my below code:
variable declation I have removed:
using namespace std;
using namespace boost;
void *SocketHandler(void *);
int main(int argv, char **argc)
{
pthread_t thread_id = 0;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if (hsock == -1)
{
printf("Error initializing socket %dn", errno);
goto FINISH;
}
p_int = (int *) malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1)
|| (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1))
{
printf("Error setting options %dn", errno);
free(p_int);
goto FINISH;
}
free(p_int);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1)
{
fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
goto FINISH;
}
if (listen(hsock, 10) == -1)
{
fprintf(stderr, "Error listening %dn", errno);
goto FINISH;
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
int pid;
pid_t pid=fork();
if(pid<0)
exit(EXIT_FAILURE);
else if(pid>0){
//this is parent process, exit now
exit(EXIT_SUCCESS); // again no goto
}
else{
//this is child or daemon
unmask();
pid_t childid = setsid();
while (true)
{
printf("waiting for a connectionn\n");
csock = (int *) malloc(sizeof(int));
if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1)
{
printf("---------------------nReceived connection from %s\n", inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
}
else
{
fprintf(stderr, "Error accepting %dn", errno);
}
sleep(60);
}
FINISH:
;
}
void *SocketHandler(void *lp)
{
char *ch;/* stores references to 50 words. */
char *ch2[50] = { 0 };
char *excluded_string;
char *word;
if ((bytecount = recv(*csock, (char*) rcv.c_str(), rcv.length(), 0)) == -1)
{
fprintf(stderr, "Error receiving data %d \n", errno);
goto FINISH;
}
do
{
bytesReceived = recv(*csock, buffer.data(), buffer.size(), 0);
// append string from buffer.
if ( bytesReceived == -1 )
{
fprintf(stderr, "Error receiving data %d \n", errno);
goto FINISH;
}
else
rcv.append( buffer.cbegin(), buffer.cend() );
} while ( bytesReceived == MAX_BUF_LENGTH );
word = strtok(& rcv[0]," ");
while (word!= NULL)
{
skp = BoyerMoore_skip(word, strlen(word) );
if(skp != NULL)
{
i++;
printf("this also \n");
word = strtok(NULL, " ");
continue;
}
printf("\n Word %s \n",word);
bfr << word << " ";
result_string = bfr.str();
word = strtok(NULL, " ");
j++;
}
ss<<result_string;
while (std::getline(ss, item, ' '))
{
writable.push_back(item);
}
for (std::vector < std::string >::iterator it = writable.begin(); it != writable.end(); it++)
++src[*it];
std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()), mytransform);
rec=dst.begin();
for (auto it = dst.begin(); it != dst.end(); ++it)
std::cout << it->second << ":" << it->first << std::endl;
if ((bytecount = send(*csock, (char *)ar, i *sizeof(int), 0)) == -1)
{ // Here we cant send lenth-1. It consider exact
fprintf(stderr, "Error sending data %d\n", errno);
goto FINISH;
}
FINISH:
free(csock);
return 0;
}
#include <sys/types.h>
#include <unistd.h>
pid_t pid=fork();
if(pid<0)
exit(EXIT_FAILURE); //see no goto
else if(pid>0){
//this is parent process, exit now
exit(EXIT_SUCCESS); // again no goto
}
else{
//this is child or daemon
unmask();
pid_t childid = setsid();
while(true){
myTask(); //Run the Process
sleep(60);
}
}
Ok I studied your program and made changes. This is how your code in main should look like.
using namespace std;
using namespace boost;
#define CHECK_THROW(condtion, code) if(condition) throw code
void *SocketHandler(void *);
int OpenSockets();
int main(int argv, char **argc)
{
try{
pid_t pid = fork();
CHECK_THROW(pid<0, -5);
if(pid==0)
{
//this is child or daemon
mode_t oldMask, newMask;
oldMask=unmask(newMask);
pid_t childid = setsid();
int hsock = OpenSocket();
CHECK_THROW(listen(hsock, 10) == -1, -4);
addr_size = sizeof(sockaddr_in);
while (true)
{
printf("waiting for a connectionn\n");
csock = (int *) malloc(sizeof(int));
*csock = accept(hsock, (sockaddr *) & sadr, &addr_size);
CHECK_THROW(*csock!=-1, -7);
printf("---------------------nReceived connection from %s\n", inet_ntoa(sadr.sin_addr));
pthread_t thread_id = pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
}
}
}
catch(int ierror)
{
switch(ierror)
{
case -4: fprintf(stderr, "Error listening %dn", errno); break;
case -7: fprintf(stderr, "Error accepting %dn", errno); break;
}
}
}
int OpenSockets()
{
// Create your socket and return the socket handle from this function
}
void *SocketHandler(void *lp){ /*blah blah */ }

daemon socket listening in background for request

I have two process: daemon and client. Both are different sockets. Initially I execute deamon socket by
./daemon and then ./client.
But I wanted that daemon process should listen in background always for the request from client. So using fork() I tried to create such a process.
I just edited the original code.
Now when I can compile daemon files and create executable daemon.
But when I send request ./client it does not respond. And says error connecting socket 111.
daemon is listening on 1104 and client sending request on the same.
When I exucte ./daemon it says
Error binding to socket, make sure nothing else is listening on this port 22n
Means it running in the back ground but not responding on request.
Code:
#include <fcntl.h>
#include <string.h>
#include <algorithm>
#include "dictionary_exclude.h"
#pragma GCC diagnostic ignored "-Wwrite-strings"
#define CHECK_THROW(condition, code) if(condition) throw code
void *SocketHandler(void *);
int OpenSocket();
int main(int argv, char **argc)
{
int host_port = 1104;
char buf[20];
int k;
struct sockaddr_in my_addr;
int hsock;
int *p_int;
int err;
socklen_t addr_size = 0;
int *csock;
sockaddr_in sadr;
pthread_t thread_id = 0;
try {
pid_t pid = fork();
CHECK_THROW(pid < 0, -5);
if (pid == 0) {
mode_t umask(mode_t mask);
pid_t childid = setsid();
hsock = OpenSocket(); // Function call for hsock
CHECK_THROW(listen(hsock, 10) == -1, -4);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) {
fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
exit(EXIT_SUCCESS);
}
if (listen(hsock, 10) == -1) {
fprintf(stderr, "Error listening %dn", errno);
exit(EXIT_SUCCESS);
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
while (true) {
printf("waiting for a connectionnn");
csock = (int *) malloc(sizeof(int));
if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) {
printf("---------------------nReceived connection from %sn", inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
} else {
fprintf(stderr, "Error accepting %dn", errno);
}
} //while end
} //if (pid) end
} //try
catch(int ierror) {
switch (ierror) {
case -4:
fprintf(stderr, "Error listening %dn", errno);
break;
case -7:
fprintf(stderr, "Error accepting %dn", errno);
break;
}
}
}
int OpenSocket()
{
// Create your socket and return the socket handle from this function
int hsock;
int *p_int;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if (hsock == -1) {
printf("Error initializing socket %dn", errno);
exit(EXIT_SUCCESS);
}
p_int = (int *) malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) {
printf("Error setting options %dn", errno);
free(p_int);
exit(EXIT_SUCCESS);
}
free(p_int);
return hsock;
}
void *SocketHandler(void *lp)
{
//some procesing
}
Can some one say is there any problem in above code.
Original code was:
int main(int argv, char **argc)
{
int host_port = 1104;
char buf[20];
int k;
struct sockaddr_in my_addr;
int hsock;
int *p_int;
int err;
socklen_t addr_size = 0;
int *csock;
sockaddr_in sadr;
pthread_t thread_id = 0;
try {
pid_t pid = fork();
CHECK_THROW(pid < 0, -5);
if (pid == 0) {
mode_t umask(mode_t mask);
pid_t childid = setsid();
hsock = OpenSocket(); // Function call for hsock
CHECK_THROW(listen(hsock, 10) == -1, -4);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) {
fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
exit(EXIT_SUCCESS);
}
if (listen(hsock, 10) == -1) {
fprintf(stderr, "Error listening %dn", errno);
exit(EXIT_SUCCESS);
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
while (true) {
printf("waiting for a connectionnn");
csock = (int *) malloc(sizeof(int));
if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) {
printf("---------------------nReceived connection from %sn", inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
} else {
fprintf(stderr, "Error accepting %dn", errno);
}
} //while end
} //if (pid) end
} //try
catch(int ierror) {
switch (ierror) {
case -4:
fprintf(stderr, "Error listening %dn", errno);
break;
case -7:
fprintf(stderr, "Error accepting %dn", errno);
break;
}
}
}
int OpenSocket()
{
// Create your socket and return the socket handle from this function
int hsock;
int *p_int;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if (hsock == -1) {
printf("Error initializing socket %dn", errno);
exit(EXIT_SUCCESS);
}
p_int = (int *) malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) {
printf("Error setting options %dn", errno);
free(p_int);
exit(EXIT_SUCCESS);
}
free(p_int);
return hsock;
}
void *SocketHandler(void *lp)
{
//some procesing
}
You are calling listen before you call bind - you should call bind first.
Actually, you are calling listen twice, both before and after calling bind. Remove the first call.
hsock = OpenSocket();
// remove this line:
CHECK_THROW(listen(hsock, 10) == -1, -4);
my_addr.sin_family = AF_INET;
Another improvement: use strerror or perror to generate the error message so that you get a user friendly message. For example:
perror("Error binding to socket");
exit(EXIT_SUCCESS);
The solution was pretty easy:
No need for big coding, just & will do everything.
inplace of executing ./daemon use ./daemon &. This will keep daemon processing listening in back

TCP Winsock: accept multiple connections/clients

I tried to can multiply clients, and send it to each one.
But it working only for one, after one client connected the server just useless for incoming connections.
while(true)
{
if(Sub = accept(Socket, (sockaddr*)&IncomingAddress, &AddressLen))
{
for(int i = 0; i < MaxUsers; i++)
{
if(!ClientAddress[i].sin_family)
{
ClientAddress[i] = IncomingAddress;
char Version[128], Dir[256], Path[256], URL[128], Message[256];
GetCurrentDirectory(256, Dir);
sprintf(Path, "%s\\Version.ini", Dir);
GetPrivateProfileString("Default", "Version", "1.0.0.0", Version, 128, Path);
GetPrivateProfileString("Default", "URL", "", URL, 128, Path);
GetPrivateProfileString("Default", "Message", "", Message, 256, Path);
send(Sub, Version, 128, 0);
send(Sub, Message, 256, 0);
break;
}
}
continue;
}
}
Of course new clients cannot be accepted because the server handles just accepted client, i.e. the server is busy.
The solution is simple: create a new thread for each accepted client and handle the client session there. Just use _beginthreadex() (#include <process.h>):
unsigned __stdcall ClientSession(void *data)
{
SOCKET client_socket = (SOCKET)data;
// Process the client.
}
int _tmain(int argc, _TCHAR* argv[])
{
...
SOCKET client_socket;
while ((client_socket = accept(server_socket, NULL, NULL))) {
// Create a new thread for the accepted client (also pass the accepted client socket).
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)client_socket, 0, &threadID);
}
}
By the way, send()/recv() functions do not guarantee that all the data would be sent/received at one call. Please see the documentation for return value of these functions.
After accepting socket create separate thread for client requests. Then continue wait for new accepting.
For example:
...
while (1)
{
AcceptSocket = SOCKET_ERROR;
while (AcceptSocket == SOCKET_ERROR )
{
AcceptSocket = accept( m_socket, NULL, NULL );
}
printf( "Client Connected.\n");
DWORD dwThreadId;
CreateThread (NULL, 0, ProcessClient, (LPVOID) AcceptSocket, 0, &dwThreadId);
}
...
Where ProcessClient function could be like this:
DWORD WINAPI ProcessClient (LPVOID lpParameter)
{
SOCKET AcceptSocket = (SOCKET) lpParameter;
// Send and receive data.
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[2000]="";
char recvbuf[2000]="";
char timebuf[128];
sprintf(sendbuf, "Hello, it's a test server at %s:%d (commands: 1, 2, exit)\n", ipaddr, port);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send hello: %ld\n", WSAGetLastError());
goto fin;
}
while (1)
{
_strtime( timebuf );
ZeroMemory (recvbuf, sizeof(recvbuf));
bytesRecv = recv( AcceptSocket, recvbuf, 32, 0);
printf( "%s Client said: %s\n", timebuf, recvbuf);
if (strcmp(recvbuf, "1") == 0)
{
sprintf(sendbuf, "You typed ONE\n");
//printf("Sent '%s'\n", sendbuf);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send: %ld\n", WSAGetLastError());
goto fin;
}
}
else if (strcmp(recvbuf, "2") == 0)
{
sprintf(sendbuf, "You typed TWO\n");
//printf("Sent '%s'\n", sendbuf);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send: %ld\n", WSAGetLastError());
goto fin;
}
}
else if (strcmp(recvbuf, "exit") == 0)
{
printf( "Client has logged out\n", WSAGetLastError());
goto fin;
}
else
{
sprintf(sendbuf, "unknown command\n");
//printf("Sent '%s'\n", sendbuf);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send: %ld\n", WSAGetLastError());
goto fin;
}
}
}
fin:
printf("Client processed\n");
closesocket(AcceptSocket);
return 0;
}