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 */ }
Related
New to socket programming, trying to implement a TCP server, but accept() returns -1 and errno = 9 (bad file descriptor). The problem arose after I introduced the accept() function in the freertos task. I really don’t understand what the problem is here, because before this my action everything worked, but I need to use the task.
#include "TCP.hpp"
#include <iostream>
#include <cmath>
#include <cerrno>
#include <cstring>
#include <clocale>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "freertos/queue.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "ping/ping_sock.h"
#include "errno.h"
static const char *TAG = "TCP";
QueueHandle_t TCP::xQueue1 = NULL;
ip_addr_t TCP::target_addr;
int TCP::ip_protocol;
int TCP::listen_sock;
sockaddr_in TCP::servaddr;
sockaddr_in TCP::cliaddr;
char TCP::addr_str[128];
char TCP::buf[128];
int TCP::sock;
TCP::Clbk_t TCP::clbk_tcp_recv = nullptr;
sockaddr_storage TCP::source_addr;
typedef struct
{
int len;
void * dataPtr;
}message;
void TCP::tcp_set_Clbk(Clbk_t clbk)
{
clbk_tcp_recv = clbk;
}
void TCP::tcp_create_server(sa_family_t serv_family, in_addr_t serv_addr, in_port_t serv_port)
{
int opt = 1;
struct sockaddr_in6 *servaddrPtr;
if (serv_family == AF_INET){
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_len = 24;
servaddr.sin_family = serv_family;
servaddr.sin_addr.s_addr = serv_addr;
servaddr.sin_port = htons(serv_port);
ip_protocol = IPPROTO_IP;
} else if (serv_family == AF_INET6){
servaddrPtr = (struct sockaddr_in6 *)&servaddr;
servaddrPtr->sin6_len = 24;
servaddrPtr->sin6_family = serv_family;
servaddrPtr->sin6_port = htons(serv_port);
ip_protocol = IPPROTO_IPV6;
}
ESP_LOGI(TAG, "Create socket...\n");
if ((listen_sock = socket(serv_family, SOCK_STREAM, ip_protocol)) < 0) {
ESP_LOGE(TAG, "socket not created\n");
}
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
ESP_LOGI(TAG, "Socket created");
int err = bind(listen_sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
if (err != 0) {
ESP_LOGE(TAG, "Socket unable to bind errno %d", errno);
ESP_LOGE(TAG, "IPPROTO: %d", serv_family);
goto CLEAN_UP;
}
ESP_LOGI(TAG, "Socket bound, port %d", serv_port);
err = listen(listen_sock, 1);
if (err != 0) {
ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno);
goto CLEAN_UP;
}
ESP_LOGI(TAG, "Soccket listening . . .");
xTaskCreate(tcp_listening_task, "tcp_listening_task", 4096, nullptr, 5, nullptr);
CLEAN_UP:
close(listen_sock);
}
void TCP::tcp_listening_task(void *arg)
{
int keepAlive = 1;
socklen_t addr_len = sizeof(source_addr);
ESP_LOGI(TAG, "Socket %d ",listen_sock);
for (;;) {
sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
ESP_LOGI(TAG, "Socket %d ",sock);
if (sock < 0) {
ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
}
if (sock > 0) {
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(int));
if (source_addr.ss_family == PF_INET) {
inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
}
else if (source_addr.ss_family == PF_INET6) {
inet6_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
}
ESP_LOGI(TAG, "Socket %d accepted ip address: %s",sock, addr_str);
xTaskCreate(tcp_task_recv, "tcp_task_recv", 4096, nullptr, 5, nullptr);
}
}
}
void TCP::tcp_task_recv(void *arg)
{
int n;
int number_receiving = 0;
struct timeval tv;
tv.tv_sec = 1;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));
ESP_LOGI(TAG,"server waiting message");
for (;;) {
n = recv(sock, (char *)buf, sizeof(buf), 0);
if (n < 0) {
ESP_LOGE(TAG, "Error occurred during receiving: errno %d", errno);
number_receiving++;
if (number_receiving == 10) {
number_receiving = 0;
}
}
else if (n == 0) {
ESP_LOGW(TAG, "Connection closed");
number_receiving = 0;
}
else {
if (clbk_tcp_recv != nullptr) clbk_tcp_recv(buf, n, (struct sockaddr *)&source_addr);
number_receiving = 0;
}
}
}
void TCP::tcp_sendd(void *data, uint32_t length)
{
static message msg;
xQueue1 = xQueueCreate(10, sizeof(message));
xTaskCreate(tcp_task_send, "udp_task_send", 4096, nullptr, 5, nullptr);
if(sock < 0){
ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
return;
}
if(xQueue1 == NULL){
ESP_LOGE(TAG, "queue is null");
return;
}
msg.dataPtr = data;
msg.len = length;
xQueueSend(xQueue1, (void *)&msg, portMAX_DELAY);
}
void TCP::tcp_task_send(void *arg)
{
message pxRxedMessage;
for(;;)
{
xQueueReceive(xQueue1, (void *)&pxRxedMessage, portMAX_DELAY);
int err = send(sock, pxRxedMessage.dataPtr, pxRxedMessage.len, 0);
if (err < 0){
ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
}
}
}
I tried to look for information on this issue, but since. I'm also new to c++ programming, nothing worked out
You should be passing the listen_sock as the arg parameter to tcp_listening_task(), rather than using a static class member, eg:
int listen_sock = socket(...);
...
xTaskCreate(tcp_listening_task, "tcp_listening_task", 4096, reinterpret_cast<void*>(listen_sock), 5, nullptr);
...
void TCP::tcp_listening_task(void *arg)
{
int listen_sock = reinterpret_cast<int>(arg);
...
close(listen_sock);
}
And especially the same with sock and tcp_task_recv() too, since your server is designed to handle multiple clients being connected simultaneously, which you can't handle with a single static sock variable:
int sock = accept(...);
...
xTaskCreate(tcp_task_recv, "tcp_task_recv", 4096, reinterpret_cast<void*>(sock), 5, nullptr);
...
void TCP::tcp_task_recv(void *arg)
{
int sock = reinterpret_cast<int>(arg);
...
close(sock);
}
I'm trying to make a simple heartbeat check from client to server and vice-versa, if connection on either is broken off unexpectedly it prints a message and calls closesocket.
I spent 8 hours on this and it still isn't acceptable to my mentor. Right now I got something that works, but if breakpoint is placed before while loop and connected client is forcefully closed, trying to go past breakpoint causes crash when it should break the loop and write out error.
Server side code:
int main(int argc, char *argv[])
{
SOCKET s, sa;
WSAData oWSAData;
WORD wVersion = 0x0001;
WSAStartup(wVersion, &oWSAData);
s = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in srv_address;
memset(&srv_address, 0, sizeof(srv_address));
srv_address.sin_family = AF_INET;
srv_address.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
srv_address.sin_port = htons(1099);
bind(s, (sockaddr*) &srv_address, sizeof(srv_address));
int l = listen(s, 10);
if (l < 0)
printf("Listen error\n");
else
{
printf("Listen OK. Listening on port %u\n",
htons(srv_address.sin_port));
sa = accept(s, NULL, NULL);
while (true)
{
char buffer[1000];
int nRecvLen = recv(sa, buffer, 999, 0);
buffer[nRecvLen] = '\0';
int r = recv(sa, NULL, 0, 0);
if (r == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)
{
printf("Konekcija je naglo prekinuta!\n");
break;
}
else
{
if (nRecvLen > 0)
{
for (int i = 0; i < nRecvLen; i++)
{
cout << buffer[i];
}
}
}
}
closesocket(sa);
closesocket(s);
}
WSACleanup();
return 0;
}
and client side:
int main()
{
SOCKET s;
WSAData oWSAData;
WORD wVersion = 0x0001;
WSAStartup(wVersion, &oWSAData);
s = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in srv_address;
memset(&srv_address, 0, sizeof(srv_address));
srv_address.sin_family = AF_INET;
srv_address.sin_addr.S_un.S_un_b.s_b1 = xxx;
srv_address.sin_addr.S_un.S_un_b.s_b2 = xxx;
srv_address.sin_addr.S_un.S_un_b.s_b3 = x;
srv_address.sin_addr.S_un.S_un_b.s_b4 = xxx;
srv_address.sin_port = htons(1099);
int c = connect(s, (sockaddr*) &srv_address, sizeof(srv_address));
if (c < 0)
{
printf("Connection error\n");
cout << (WSAGetLastError());
}
else
{
string l = "Heartbeat\n";
int p = l.size();
char buff[1000];
strcpy_s(buff, l.c_str());
printf("Connected\n");
while (true)
{
if (send(s, buff, p, 0) > 0)
{
Sleep(1000);
}
else
{
printf("Konekcija je naglo prekinuta\n");
shutdown(s, SD_BOTH);
closesocket(s);
break;
}
}
WSACleanup();
return 0;
}
}
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;
}
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
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.