Yamaha32088
Yamaha32088

Reputation: 4163

Transmitting data over TCP always stops at 251 transmits

I am transmitting integers over TCP I have been working at getting this to work correctly for a couple days now and I am very close. What I am doing is taking input from a USB joystick and sending the values of the Axis to the client. I have that working but my problem is that it always stops at 251. What I mean is I setup a variable that increments by 1 every single time the value of the Axis is printed to the screen on the client. I have played around with MAXRCVLEN but it still keeps stopping at 251. Can anyone look at my code and see if I am doing something wrong here?

This is the server.c file:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

//joysick libraries
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/joystick.h>

//Joysick device
#define JOY_DEV "/dev/input/js0"

//TCP Port number
#define PORTNUM 2343

int main(int argc, char *argv[])
{

    //TCP connect
    struct sockaddr_in dest; /* socket info about the machine connecting to us */
    struct sockaddr_in serv; /* socket info about our server */
    int mysocket;            /* socket used to listen for incoming connections */
    socklen_t socksize = sizeof(struct sockaddr_in);

    memset(&serv, 0, sizeof(serv));           /* zero the struct before filling the fields */
    serv.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
    serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
    serv.sin_port = htons(PORTNUM);           /* set the server port number */

    mysocket = socket(AF_INET, SOCK_STREAM, 0);

    /* bind serv information to mysocket */
    bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));

    /* start listening, allowing a queue of up to 1 pending connection */
    listen(mysocket, 1);
    int consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);

    //TCP variable
    char msg1[10];


    //Joystick variables
    int xAxis;
    int yAxis;
    int xSpeed;
    int ySpeed;

    //Joystick initialize
    int joy_fd, *axis=NULL, num_of_axis=0, num_of_buttons=0, x;
    char *button=NULL, name_of_joystick[80];
    struct js_event js;

    if( ( joy_fd = open( JOY_DEV , O_RDONLY)) == -1 )
    {
        printf( "Couldn't open joystick\n" );
        return -1;
    }

    //Get number of axes, buttons and name of joystick. Print results to screen
    ioctl( joy_fd, JSIOCGAXES, &num_of_axis );
    ioctl( joy_fd, JSIOCGBUTTONS, &num_of_buttons );
    ioctl( joy_fd, JSIOCGNAME(80), &name_of_joystick );

    axis = (int *) calloc( num_of_axis, sizeof( int ) );
    button = (char *) calloc( num_of_buttons, sizeof( char ) );

    printf("Joystick detected: %s\n\t%d axis\n\t%d buttons\n\n"
           , name_of_joystick
           , num_of_axis
           , num_of_buttons );

    //Use non blocking mode for joystick
    fcntl( joy_fd, F_SETFL, O_NONBLOCK );   /* use non-blocking mode */

    //infinite loop for reading joystick
    while(1) {

        //loop for tcp connection
        while(consocket){
            /* read the joystick state */
            read(joy_fd, &js, sizeof(struct js_event));

            /* see what to do with the event */
            switch (js.type & ~JS_EVENT_INIT)
            {
                case JS_EVENT_AXIS:
                    axis   [ js.number ] = js.value;
                    break;
                case JS_EVENT_BUTTON:
                    button [ js.number ] = js.value;
                    break;
            }
            //Give msg1 variable the value of axis[0]
            sprintf(msg1, "%d", axis[0]);

            //TCP send

            char msg[] = "Hello";
            printf("Value is: %d\n", axis[0]);
            //printf("Incoming connection from %s - sending welcome\n", inet_ntoa(dest.sin_addr));
            send(consocket, msg1, strlen(msg1), 0);
            consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
            printf("Value X is: %s\n", msg1);
            printf(" \r");
            fflush(stdout);
        }

        close(consocket);
        close(mysocket);
        return EXIT_SUCCESS;

    }

    //Joystick close
    close( joy_fd );    /* too bad we never get here */
    return 0;
}

This is the client.c file

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define MAXRCVLEN 10000
#define PORTNUM 2343

int main(int argc, char *argv[])
{
    int i = 0;
    while(1){
        char buffer[MAXRCVLEN + 1]; /* +1 so we can add null terminator */
        int len, mysocket;
        struct sockaddr_in dest;

        mysocket = socket(AF_INET, SOCK_STREAM, 0);

        memset(&dest, 0, sizeof(dest));                /* zero the struct */
        dest.sin_family = AF_INET;
        dest.sin_addr.s_addr = inet_addr("192.168.254.16"); /* set destination IP number */
        dest.sin_port = htons(PORTNUM);                /* set destination port number */

        connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr));

        len = recv(mysocket, buffer, MAXRCVLEN, 0);

        /* We have to null terminate the received data ourselves */
        buffer[len] = '\0';

        printf("Received %s (%d bytes).\n", buffer, len);
        printf("Number is: %d", i);
        i++;
        //close(mysocket);
    }
    return EXIT_SUCCESS;
}

Upvotes: 0

Views: 219

Answers (2)

Yamaha32088
Yamaha32088

Reputation: 4163

What happens if you put close(consocket) before the accept in your server? And you could just not call connect or accept inside of your loops.

This is what I mean about adding the close line. Does that help? (that should be the loop in your server code)

These comments by @Xymostech solved the problem for me!

Upvotes: 0

hookenz
hookenz

Reputation: 38947

The problem is you're connecting a TCP socket every time in the client loop. Then you're accepting the new connection every time around the loop in the server loop.

The 256 is probably related to not closing the old discarded socket each time and it's running out of per process resources or file handles.

This is not the right way to write a client/server app.

What you should do is accept a connection just ONCE, before you enter the loop. Then send as long as required, but don't send until you actually have a connected socket (obtained by the accept).

The client should connect just ONCE before the loop and when connected it should call recv inside that loop. If there is an error it can then call connect again.

There are some really great examples and details of how to write basic client/server apps using sockets in Beej's guide to Network Programming which is one of the best resources out there for socket programming.

Upvotes: 2

Related Questions