Reputation: 4163
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
Reputation: 4163
What happens if you put
close(consocket)
before theaccept
in your server? And you could just not callconnect
oraccept
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
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