LinuxQuestions.org
Visit Jeremy's Blog.
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 07-17-2009, 06:50 PM   #1
stuffradio
LQ Newbie
 
Registered: Sep 2005
Posts: 10

Rep: Reputation: 0
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!
 
Old 07-17-2009, 07:40 PM   #2
jhwilliams
Senior Member
 
Registered: Apr 2007
Location: Portland, OR
Distribution: Debian, Android, LFS
Posts: 1,168

Rep: Reputation: 208Reputation: 208Reputation: 208
* 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.
 
Old 07-20-2009, 01:41 AM   #3
stuffradio
LQ Newbie
 
Registered: Sep 2005
Posts: 10

Original Poster
Rep: Reputation: 0
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?
 
Old 07-21-2009, 01:32 AM   #4
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.6, Centos 5.10
Posts: 16,324

Rep: Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041Reputation: 2041
Why not just do it from C : http://dev.mysql.com/doc/refman/5.0/en/c.html ?
 
  


Reply

Tags
programming, server, socket


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
Putty:server unexpectedly closed network connection dyool Ubuntu 8 03-07-2012 09:35 PM
kdm[****]: X server for display :0 terminated unexpectedly http:// Linux - Newbie 2 07-14-2008 02:20 PM
Server rebooted unexpectedly, no boot of OS due to GRUB error 22 igreenhalgh Debian 3 11-06-2006 04:09 AM
cannot read data at server socket, though client socket sends it jacques83 Linux - Networking 0 11-15-2005 02:58 PM
Server Unexpectedly died (was i hacked?) gabadoo Linux - General 2 03-13-2002 02:33 AM


All times are GMT -5. The time now is 03:29 PM.

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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration