简体   繁体   English

通过TCP传输数据始终在251传输时停止

[英]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. 我通过TCP传输整数我一直在努力使这个正常工作几天,我非常接近。 What I am doing is taking input from a USB joystick and sending the values of the Axis to the client. 我正在做的是从USB操纵杆输入输入并将Axis的值发送到客户端。 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. 我有这个工作,但我的问题是它始终停在251.我的意思是我设置一个变量,每当Axis的值打印到客户端的屏幕上时,该变量递增1。 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? 我玩过MAXRCVLEN但它仍然在251停止。任何人都可以查看我的代码,看看我在这里做错了吗?

This is the server.c file: 这是server.c文件:

#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 这是client.c文件

#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;
}

The problem is you're connecting a TCP socket every time in the client loop. 问题是您每次都在客户端循环中连接TCP套接字。 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. 256可能与每次不关闭旧丢弃的套接字有关,并且每个进程资源或文件句柄耗尽。

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. 你应该做的是在进入循环之前接受ONCE连接。 Then send as long as required, but don't send until you actually have a connected socket (obtained by the accept). 然后根据需要发送,但是在你实际拥有连接套接字(由accept获得)之前不要发送。

The client should connect just ONCE before the loop and when connected it should call recv inside that loop. 客户端应该在循环之前连接ONCE,并且在连接时它应该在该循环内调用recv。 If there is an error it can then call connect again. 如果有错误,则可以再次调用connect。

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. Beej的网络编程指南中 ,如何使用套接字编写基本的客户端/服务器应用程序有一些非常好的示例和详细信息,这是套接字编程的最佳资源之一。

What happens if you put close(consocket) before the accept in your server? 如果您在服务器中accept之前放置close(consocket)会发生什么? And you could just not call connect or accept inside of your loops. 你可以不在connect调用connectaccept

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! @Xymostech的这些评论为我解决了这个问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM