LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-23-2010, 03:56 AM   #1
taabish
LQ Newbie
 
Registered: Dec 2010
Posts: 3

Rep: Reputation: 0
Application to listen at multiple ports


Hello Friends:
This is my first post at the forum. I am using a C application which connects to various other C applications at different ports through TCP,sends requests to all of them and then waits for the responses. The problem is that when the requests are fewer it gives a good response but with the increase in load the port at which the master application is listening get hogs and is unable to receive the responses.
Can you please suggest the best way to tackle this issue? Is it possible for the master application to listen at multiple ports so that the load gets distributed and how?
 
Old 12-23-2010, 04:20 AM   #2
eSelix
Senior Member
 
Registered: Oct 2009
Location: Wroclaw, Poland
Distribution: Arch, Kubuntu
Posts: 1,281

Rep: Reputation: 320Reputation: 320Reputation: 320Reputation: 320
Distribution network load on different ports will not give you anything. "Port" is only virtual term. All ports are bound to exactly one input on your network card. For this purpose you need many network cards. But first you should optimize your application. About how many requests you say, that it blocks your connection? You said that your application sends requests on different ports - you known, you have only 65536 ports available on your system?
 
Old 12-23-2010, 04:40 AM   #3
taabish
LQ Newbie
 
Registered: Dec 2010
Posts: 3

Original Poster
Rep: Reputation: 0
Let me explain in detail:
I have a master application(say for example which listens on port 9090) and which connects to 15 other applications as for now. Now when all the 15 applications sends response simultaneously to my master application the port of master application gets hog and I need to take restart for the same. After restarting my master application it works fine.
Please note that all the application are running on the same Linux Server. A maximum of 5-6 lacks request is received per day.
 
Old 12-23-2010, 03:18 PM   #4
eSelix
Senior Member
 
Registered: Oct 2009
Location: Wroclaw, Poland
Distribution: Arch, Kubuntu
Posts: 1,281

Rep: Reputation: 320Reputation: 320Reputation: 320Reputation: 320
Only 15 applications? It is very small load. And if you use TCP then all packets should be delivered, your system take care of this. Look at web servers, they can receive thousands connections simultaneously with one network card on one port. You definitely have some bug in your application. The best will be to paste your code for server and clients, if you can.
 
Old 12-23-2010, 03:43 PM   #5
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Either your application is poorly coded, or the volume of data &/or processing is high, relative to the CPU speed. 15 simultaneous connections is not a very high number. Web servers, mail servers, and other such application routinely handle far more connections than that.

--- rod.
 
Old 12-23-2010, 10:37 PM   #6
taabish
LQ Newbie
 
Registered: Dec 2010
Posts: 3

Original Poster
Rep: Reputation: 0
This is the thread where master application waits for the responses:
void pp_mc_server_thread(void *dummy)
{

fd_set fd_readset;
int result;
pp_req_resp_t *p_rc_resp;

debug_print("pp_mc_server_thread: Started");

while(g_app_status)
{

FD_ZERO(&fd_readset);

FD_SET((unsigned int) g_mc_server_sockfd, &fd_readset);

debug_print("pp_mc_server_thread: Waiting For Connection Request From Apps");

result = select(FD_SETSIZE, &fd_readset, NULL, NULL, NULL);

if(result <= 0)
{
err_print("pp_mc_server_thread: Select failure in Server Socket, Exiting!!!");
g_app_status = 0;
break;
}

debug_print("pp_mc_server_thread: Connection Request From Apps");

//Check for data on Master Client Server Socket Fd
if (FD_ISSET (g_mc_server_sockfd, &fd_readset))
{
g_mc_conn_sockfd = pp_accept (g_mc_server_sockfd);
debug_print("pp_mc_server_thread: Received [%s] with pp_accept",strerror(errno));
if (g_mc_conn_sockfd < 0)
{
err_print("pp_mc_server_thread: Accept Failed");
continue;
}

debug_print("pp_mc_server_thread: Connected To Apps");
p_rc_resp = (pp_req_resp_t *)malloc(sizeof(pp_req_resp_t));
memset(p_rc_resp,0,sizeof(pp_req_resp_t));
sleep(1);
if (pp_read(g_mc_conn_sockfd, (char *) p_rc_resp, sizeof(pp_req_resp_t)) <= 0)
{

err_print("pp_mc_server_thread: Error in reading Req/Resp From Connection for %s", p_rc_resp->req_id);
pp_disconnect(g_mc_conn_sockfd);
free(p_rc_resp);
}
else
{
//Process Apps Response
pp_proc_rc_resp(p_rc_resp);
}
pp_disconnect(g_mc_conn_sockfd);
}

}
debug_print("pp_mc_server_thread: Exited");

return;

}

And this his how all the clients send the response to the master client:
int pp_send_resp_to_mc(pp_req_resp_t *req)
{
int result;
pp_req_resp_t resp_ack;
struct timeval timeout;
fd_set fd_readset;

//Create connection with Master Client Server
g_mc_conn_sockfd = pp_connect(g_mc_server_port, g_mc_ip_addr);

if (g_mc_conn_sockfd < 0)
{
err_print("pp_send_resp_to_mc: Unable to Open Connection with Server");
if(req!=NULL)
{
debug_print("\n pp_send_resp_to_mc: 3 req = %d",req);
free(req);
req=NULL;
}
return PP_FALSE;
}
debug_print("pp_send_resp_to_mc: Connected To Server");

//Send response to Server
errno = 0;
usleep(1000);
result = pp_write (g_mc_conn_sockfd, (char *) req, sizeof(pp_req_resp_t));
debug_print("Received [%s] with pp_write for SOID %s and the result is %d",strerror(errno),req->req_id,result);
if (result < sizeof(pp_req_resp_t) )
{
err_print("pp_send_resp_to_mc: Failed to Send Response to Server for %s", req->req_id);
pp_disconnect(g_mc_conn_sockfd);
g_mc_conn_sockfd = -1;
if(req!=NULL)
{
debug_print("\n pp_send_resp_to_mc: 4 req = %d",req);
free(req);
}
return PP_FALSE;
}
debug_print("pp_send_resp_to_mc: Send Response for %s", req->req_id);

//Wait for response from Server
FD_ZERO(&fd_readset);

memset(&timeout, 0, sizeof(struct timeval));
timeout.tv_sec = PP_MAX_ACK_TIME;
FD_SET((unsigned int) g_mc_conn_sockfd, &fd_readset);
errno = 0;
result = select(FD_SETSIZE, &fd_readset, NULL, NULL, &timeout);
if (result <= 0 || (FD_ISSET(g_mc_conn_sockfd, &fd_readset) == 0))
{
debug_print("Select result is less than zero %d for SOID %s",result,req->req_id);
//Timer Expired
pp_disconnect(g_mc_conn_sockfd);
g_mc_conn_sockfd = -1;
if(req!=NULL)
{
free(req);
req=NULL;
}

return PP_FALSE;
}

//Read Ack for the request
memset(&resp_ack, 0, sizeof(pp_req_resp_t));
usleep(10000);
if (pp_read(g_mc_conn_sockfd, (char *) &resp_ack, sizeof(pp_req_resp_t)) <= 0)
{
usleep(10000);
if (pp_read(g_mc_conn_sockfd, (char *) &resp_ack, sizeof(pp_req_resp_t)) <= 0)
{
debug_print("Received [%s] with pp_read for SOID %s",strerror(errno),req->req_id);

}
err_print("pp_send_resp_to_mc: Error in Reading Ack from Connection for %s",req->req_id);
pp_disconnect(g_mc_conn_sockfd);
g_mc_conn_sockfd = -1;
if(req!=NULL)
{
free(req);
req=NULL;
}
return PP_FALSE;
}
err_print("pp_send_resp_to_mc: Ack Received for %s and the result is %d",req->req_id,result);
pp_disconnect(g_mc_conn_sockfd);
g_mc_conn_sockfd = -1;
if(req!=NULL)
{
free(req);
req=NULL;
}
return PP_TRUE;
}

Please suggest.
 
Old 12-24-2010, 08:51 AM   #7
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
What is the purpose of all the sleep() and usleep() call? These could explain why the throughput is being limited.

Your code is very difficult to follow. It would be easier if it was posted in [code ][/code] tags to preserve formatting (did you not notice that everyone else does that?), and if the pieces were separated according to client vs. server components. You do understand the distinction between a client and a server, in the context of socket oriented programming, right? Your comments in the code suggest that you may not, and are confusing:
Quote:
clients send the response to the master client
There are servers and there are clients. Servers listen & accept connections, and clients connect. Either side can send or receive on a stream oriented (TCP) connection. Adding language like 'master client' may make sense to you in the context of your application, but most readers will not understand that language.

--- rod.
 
Old 12-24-2010, 11:37 AM   #8
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
It seems that the server is only servicing one client at a time. Depending on the depth of the listen-socket backlog, certain clients may not be successfully connecting to the server. The server is held up awaiting data from each and every client; this is perhaps the wrong approach. The server should only service it's listen socket; allow another process or thread to service the client(s) that connect.

As for the code, I agree with theNbomr that it is very hard to read. One thing that bugs me is the lack of modularization of the code.

Consider something similar to the following (which btw, contains some pseudo-code):
Server:
Code:
int main(...)
{
   int listen_sd = socket(...);
   ...
   bind(listen_sd, ...);

   listen(listen_sd, 5);

   while (!done)
   {
      int client_sd = accept(listen_sd, 0, 0);

      if (client_sd >= 0)
      {
         pid_t pid = fork();

         if (pid == 0)
         {
            handleClient(client_sd);
            exit(0);
         }
      }
   }

   close(listen_sd);
   return 0;
}


void handleClient(int sd)
{
   fd_set save_sd;
   FD_ZERO(&save_sd);
   FD_SET(sd, &save_sd);

   while (1)
   {
      fd_set read_sd = save_sd;
      int    sel     = select(sd + 1, &read_sd, 0, 0, 0);

      if (sel > 0)
      {
         int bytes_read = recv(sd, ...);

         if (bytes_read < 0)
         {
            /* error detected */

            /* is it non-fatal? */
            if (errno == EAGAIN)
              continue;

            /* fatal; get out of while-loop */
            break;
         }
         else if (bytes_read == 0)
         {
            /* client disconnected */
            break;
         }
         else
         {
            /* got data */
         }
      }
   }

   close(sd);
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Why can only root listen to ports below 1024? mikaelstaldal LQ Articles Discussion 4 08-21-2022 04:03 AM
[SOLVED] Why does Apache only listen to ipv6 ports? ludo33 Linux - Server 8 09-13-2009 04:55 PM
Can't find where to set certain ports to listen garf Linux - Networking 1 07-01-2006 12:06 AM
Configuring SSH to listen on two different ports at once james penguin Linux - Software 4 11-24-2005 09:08 PM
SSH listen on two ports Buto Slackware 1 10-02-2004 01:15 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:53 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration