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
Welcome to
LinuxQuestions.org , a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free.
Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please
contact us . If you need to reset your password,
click here .
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a
virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month.
Click here for more info.
07-17-2009, 05:50 PM
#1
LQ Newbie
Registered: Sep 2005
Posts: 10
Rep:
C Socket Server unexpectedly shutting down
I'm running a socket server that I found on one of the C programming websites. I've been trying this with other socket server scripts as well. It runs fine for a while, it accepts multiple clients... but then for some reason unbeknown to me, it shuts down. Also the last couple times I saw the server in the process list running, and I killed it anyways because it was not responding.
Anyone have any possible remedies for me?
Thanks!
07-17-2009, 06:40 PM
#2
Senior Member
Registered: Apr 2007
Location: Portland, OR
Distribution: Debian, Android, LFS
Posts: 1,168
* Debug it with standard GNU utilities: gdb, strace, etc.
* Invoke the daemon with a log to some file you can go look at if it spits out to stdout/stderr.
* Post some code here, or a link to the code you're talking about?
--> read and understand the code and the error conditions.
* Core dump when it quits responding, (kill -6), then gdb the dump.
07-20-2009, 12:41 AM
#3
LQ Newbie
Registered: Sep 2005
Posts: 10
Original Poster
Rep:
I'm using a different one right now, and it looks like it's working fine.
Code:
/*
* Based on:
* http://www.gnu.org/software/libc/manual/html_mono/libc.html#Server%20Example
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <syslog.h>
#include <stdarg.h>
#include <time.h>
#define PORT 1730 /* default port to listen on */
#define MAXMSG 10240
#define MAX_QUEUED_CONNS 5
#define MAX_SOCK_IDLE 10 /* minutes */
#define SECS_PER_MIN 60
/*
* Global vars.
*/
static const char gVersion[] = "@(#) tcpechoserver v1.4 " __DATE__;
const char gScaryMsg[] =
"\r\n\r\n WARNING\r\n"
" Unauthorized access to this system is forbidden and will be\r\n"
" prosecuted by law. By accessing this system, you agree that your\r\n"
" actions may be monitored if unauthorized usage is suspected.\r\n\r\n"
" Your IP address has been logged: ";
const char gDiscMsg[] = "\r\nDisconnecting due to inactivity\r\n";
char gHostNameBuf[512];
struct sockaddr_in gServerName;
int gMaxFd;
int gNumberClients;
int gDebug;
int gTcpListenSock;
int gUdpSock;
time_t gMaxSockIdle = MAX_SOCK_IDLE * SECS_PER_MIN;
time_t gSockTime[FD_SETSIZE];
fd_set gActive_fd_set;
#ifdef __CYGWIN__
/* Set default log file name for Cygwin build. */
char gLogFilename[FILENAME_MAX] = { "C:/TEMP/tcpecho.log" };
#define SYSLOG mySyslog
/* ------------------------------------------------
* mySyslog
* ------------------------------------------------
*/
static void mySyslog (int level, const char *fmt, ...)
{
static FILE *logFile = NULL;
va_list ap;
char buf[1024];
time_t logTime;
if (logFile == NULL)
{
logFile = fopen (gLogFilename, "a");
}
if (logFile != NULL)
{
va_start (ap, fmt);
vsnprintf (buf, sizeof buf, fmt, ap);
va_end (ap);
logTime = time (NULL);
fprintf (logFile, "%24.24s: %s\n", ctime (&logTime), buf);
fflush (logFile);
}
}
#else
#define SYSLOG syslog
#endif
/* ------------------------------------------------
* getRemoteHostname
* ------------------------------------------------
*/
const char * getRemoteHostname (struct sockaddr_in sin)
{
struct hostent *hp;
hp = gethostbyaddr ((char *) &sin.sin_addr,
sizeof sin.sin_addr, AF_INET);
if (hp)
{
/*
* We found a corresponding hostname, format the string one way...
*/
snprintf (gHostNameBuf, sizeof gHostNameBuf, "%s [%s]", hp->h_name,
inet_ntoa (sin.sin_addr));
}
else
{
/*
* This host not in the host tables or Domain Name Server.
*/
snprintf (gHostNameBuf, sizeof gHostNameBuf, "[%s]",
inet_ntoa (sin.sin_addr));
}
return gHostNameBuf;
}
/* ------------------------------------------------
* bindToPort
* ------------------------------------------------
*/
int bindToPort (int sockStyle)
{
int sock;
int opt;
/* Create the socket. */
sock = socket (PF_INET, sockStyle, 0);
if (sock < 0)
{
SYSLOG (LOG_USER, "socket failed");
exit (EXIT_FAILURE);
}
/*
* Set the "REUSEADDR" option on this socket. This will allow us to
* bind() to it EVEN if there already connections in progress on this
* port number. Otherwise, we would get an "Address already in use"
* error.
*/
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
{
SYSLOG (LOG_USER, "setsockopt failed");
exit (EXIT_FAILURE);
}
if (bind (sock, (struct sockaddr *) &gServerName, sizeof gServerName) < 0)
{
SYSLOG (LOG_USER, "bind failed");
exit (EXIT_FAILURE);
}
return sock;
}
/* ------------------------------------------------
* closeSock
* ------------------------------------------------
*/
void closeSock (int sock)
{
SYSLOG (LOG_USER, "connection %d: disconnecting.", sock);
close (sock);
FD_CLR (sock, &gActive_fd_set);
gNumberClients--;
}
/* ------------------------------------------------
* echoTcp
* ------------------------------------------------
*/
int echoTcp (int sock)
{
int nbytes;
char buffer[MAXMSG];
nbytes = read (sock, buffer, MAXMSG);
if (nbytes > 0)
{
/* Echo data read and log the time. */
write (sock, buffer, nbytes);
gSockTime[sock] = time(NULL);
return nbytes;
}
else
{
/* End-of-file or error. */
closeSock (sock);
return -1;
}
}
/* ------------------------------------------------
* echoUdp
* ------------------------------------------------
*/
void echoUdp (int sock)
{
int nbytes;
int size;
struct sockaddr_in sin;
char buffer[MAXMSG];
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = gServerName.sin_port;
size = sizeof sin;
nbytes = recvfrom (sock, buffer, MAXMSG, 0,
(struct sockaddr *) &sin, &size);
if (nbytes < 0)
{
SYSLOG (LOG_USER, "recfrom failed");
return;
}
/* Log the message. */
if (gDebug)
{
SYSLOG (LOG_USER, "Rcvd UDP (%d bytes) from: [%s] Port: %d",
nbytes, inet_ntoa (sin.sin_addr), ntohs(sin.sin_port));
}
/*
* If the source port is 0, we can't send the message back.
*/
if ( ntohs(sin.sin_port) != 0 )
{
/* Echo the message back to the sender. */
nbytes = sendto (sock, buffer, nbytes, 0,
(struct sockaddr *) &sin, size);
if (nbytes < 0)
{
SYSLOG (LOG_USER, "sendto failed");
return;
}
}
}
/* ------------------------------------------------
* checkIdleSockets
* ------------------------------------------------
*/
void checkIdleSockets ( void )
{
int sock;
time_t currentTime = time(NULL);
//if (gDebug) SYSLOG(LOG_USER, "checkIdleSockets");
/*
* Check for an active socket that has been idle
* for longer than gMaxSockIdle seconds.
*/
for (sock = 0; sock <= gMaxFd; ++sock)
{
if (FD_ISSET (sock, &gActive_fd_set) &&
((currentTime - gSockTime[sock]) > gMaxSockIdle ) &&
(sock != gTcpListenSock) &&
(sock != gUdpSock))
{
write (sock, gDiscMsg, sizeof gDiscMsg);
closeSock (sock);
}
}
}
/* ------------------------------------------------
* acceptNewSock
* ------------------------------------------------
*/
void acceptNewSock ( void )
{
struct sockaddr_in clientName;
int acceptSock;
int size;
char buffer[MAXMSG];
/* Accept new connection request on original socket. */
size = sizeof clientName;
acceptSock = accept (gTcpListenSock,
(struct sockaddr *) &clientName,
&size);
if (acceptSock < 0)
{
SYSLOG (LOG_USER, "accept failed");
exit (EXIT_FAILURE);
}
SYSLOG (LOG_USER,
"connection %d from %s, port %hu.",
acceptSock,
getRemoteHostname (clientName),
ntohs (clientName.sin_port));
snprintf(buffer, sizeof buffer, "%s%s\r\n\r\n",
gScaryMsg, gHostNameBuf);
write (acceptSock, buffer, strlen(buffer));
/*
* Add newly accepted socket to the active set.
*/
FD_SET (acceptSock, &gActive_fd_set);
gMaxFd = MAX(gMaxFd, acceptSock);
gSockTime[acceptSock] = time(NULL);
gNumberClients++;
}
/* ------------------------------------------------
* processSockets
* ------------------------------------------------
*/
void processSockets (fd_set *pRead_fd_set)
{
int activeSock;
/* Service all the sockets with input pending. */
for (activeSock = 0; activeSock <= gMaxFd; ++activeSock)
{
if (FD_ISSET (activeSock, pRead_fd_set))
{
if (activeSock == gTcpListenSock)
{
/*
* Accept a connection for a TCP socket.
*/
acceptNewSock ();
}
else if (activeSock == gUdpSock)
{
/*
* Echo data arriving on the UDP socket.
*/
echoUdp (activeSock);
}
else
{
/*
* Echo data arriving on a connected TCP socket.
*/
echoTcp (activeSock);
} /* if (activeSock == gTcpListenSock) */
} /* if (FD_ISSET (activeSock, pRead_fd_set)) */
} /* for (activeSock = 0; ...) */
}
/* ------------------------------------------------
* mainLoop
* ------------------------------------------------
*/
void mainLoop (void)
{
int selectResult;
fd_set read_fd_set;
struct timeval selectTimeout;
struct timeval *pSelectTimeout;
/* Create the tcp socket and set it up to accept connections. */
gTcpListenSock = bindToPort (SOCK_STREAM);
if (listen (gTcpListenSock, MAX_QUEUED_CONNS) < 0)
{
SYSLOG (LOG_USER, "listen failed");
exit (EXIT_FAILURE);
}
gUdpSock = bindToPort (SOCK_DGRAM);
/* Initialize the set of active sockets. */
FD_ZERO (&gActive_fd_set);
FD_SET (gTcpListenSock, &gActive_fd_set);
FD_SET (gUdpSock, &gActive_fd_set);
gMaxFd = MAX(gTcpListenSock, gUdpSock);
gNumberClients = 0;
while (1)
{
if ((gMaxSockIdle > 0) && (gNumberClients > 0))
{
/*
* If there are any clients connected, we'll have
* select timeout every so often so that we can
* check for idle sockets and close them if they
* have been idle too long.
*/
selectTimeout.tv_usec = 0;
selectTimeout.tv_sec = 61;
pSelectTimeout = &selectTimeout;
}
else
{
/*
* If there are no clients, or the timeout is disabled,
* we let select block until there is activity on the
* listen socket.
*/
pSelectTimeout = NULL;
}
read_fd_set = gActive_fd_set;
/* Block until input arrives on one or more active sockets. */
selectResult = select (gMaxFd+1, &read_fd_set, NULL, NULL, pSelectTimeout);
if (selectResult < 0)
{
SYSLOG (LOG_USER, "select failed");
exit (EXIT_FAILURE);
}
if (selectResult > 0)
{
processSockets (&read_fd_set);
}
if ((gMaxSockIdle > 0) && (selectResult >= 0))
{
/*
* Data received or select timed out.
*/
checkIdleSockets ();
}
} /* while (1) */
/* not reached */
}
/* ------------------------------------------------
* usage
* ------------------------------------------------
*/
void usage (const char *progname)
{
fprintf (stderr, "%s\n", gVersion);
#ifdef __CYGWIN__
fprintf (stderr, "\nusage: %s [-adhlpt]\n", progname);
#else
fprintf (stderr, "\nusage: %s [-adhpt]\n", progname);
#endif
fprintf (stderr, " -a <inetaddr> set local address for bind\n");
fprintf (stderr, " -d enable debug logging\n");
fprintf (stderr, " -h print this help\n");
#ifdef __CYGWIN__
fprintf (stderr, " -l <logfile> log to file <logfile> (default: %s)\n",
gLogFilename);
#endif
fprintf (stderr, " -p # set port for bind (default: %d)\n", PORT);
fprintf (stderr, " -t # "
"set idle socket timeout in minutes (default: %d)\n"
" zero disables timeout\n\n",
MAX_SOCK_IDLE);
}
/* ------------------------------------------------
* main
* ------------------------------------------------
*/
int main (int argc, char *argv[])
{
char ch;
char *progname;
int i;
char cmdLine[256];
int cmdIdx;
/*
* Trim path from program name.
*/
progname = rindex (argv[0], '/');
if (progname == NULL)
{
progname = argv[0];
}
else
{
progname++;
}
/* Set default socket name. */
gServerName.sin_family = AF_INET;
gServerName.sin_port = htons (PORT);
gServerName.sin_addr.s_addr = htonl (INADDR_ANY);
// Log the exact command line used to start the program.
cmdIdx = 0;
cmdIdx += sprintf(&cmdLine[cmdIdx], "# %s", progname);
for (i=1; i<argc; i++)
{
cmdIdx += sprintf(&cmdLine[cmdIdx], " %s", argv[i]);
}
/*
* Process cmd line options.
*/
#ifdef __CYGWIN__
while ((ch = getopt (argc, argv, ":dhl:a:p:t:")) != -1)
#else
while ((ch = getopt (argc, argv, ":dha:p:t:")) != -1)
#endif
{
switch (ch)
{
case 'h':
usage (progname);
exit (0);
break;
case 'd':
gDebug = 1;
break;
case 'a':
if (strcmp (optarg, "localhost") == 0)
{
gServerName.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
}
else
{
gServerName.sin_addr.s_addr = inet_addr (optarg);
if (gServerName.sin_addr.s_addr == htonl (INADDR_NONE))
{
fprintf (stderr, "Bad bind address: %s\n", optarg);
exit (-1);
}
}
break;
case 'p':
{
uint16_t port = atoi (optarg);
if (port < 1024)
{
fprintf (stderr, "Can't bind to privileged port: %hu\n",
port);
exit (-1);
}
gServerName.sin_port = htons (port);
}
break;
case 't':
gMaxSockIdle = atoi (optarg) * SECS_PER_MIN;
if (gMaxSockIdle < 0)
{
fprintf (stderr, "Error: invalid timeout value\n");
exit (-1);
}
break;
#ifdef __CYGWIN__
case 'l':
strncpy (gLogFilename, optarg, sizeof gLogFilename);
break;
#endif
default:
fprintf (stderr, "\nUnknown option");
usage (progname);
exit (-1);
break;
}
}
/*
* Close all open file descriptors.
*/
close (STDIN_FILENO);
close (STDOUT_FILENO);
close (STDERR_FILENO);
/*
* Fork to detach from shell.
*/
if (fork () != 0)
{
exit (0); /* parent exits */
}
SYSLOG (LOG_USER, cmdLine);
SYSLOG (LOG_USER, "%s : port %hu",
gVersion, ntohs (gServerName.sin_port));
if (gDebug)
{
SYSLOG (LOG_USER, "Timeout = %d secs; local addr = %s", gMaxSockIdle,
inet_ntoa (gServerName.sin_addr));
}
mainLoop (); /* does not return */
exit (0);
}
Can anyone tell me how to send data the socket server receives to a php script so I can insert the data in to a MySQL database?
07-21-2009, 12:32 AM
#4
LQ Guru
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,358
All times are GMT -5. The time now is 06:27 AM .
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know .
Latest Threads
LQ News