简体   繁体   English

Windows(客户端)和Linux之间的TCP通信

[英]TCP Communication between Windows (Client) and Linux

I'm working on a robot that is controlled by an xbox controller connected to a windows computer and commands are sent to a pcduino through a tcp connection. 我正在研究一个由连接到Windows计算机的xbox控制器控制的机器人,并通过tcp连接将命令发送到pcduino。 I have it working by sending a string of 1's and 0's to tell the pcduino which motors to turn on. 我通过发送1和0的字符串来告诉pcduino打开哪些电机。 I'm trying to optimize it by just sending an int and using bit masks to make the decisions on the pcduino but I can't get the pcduino to receive the int correctly. 我试图通过发送一个int并使用位掩码来对pcduino做出决定来优化它,但我不能让pcduino正确地接收int。 I tested the windows function sending the command with sokit and its sending the correct values but the pcduino is receiving the same number even when the commands are changing. 我测试了windows函数发送带有sokit的命令并发送了正确的值,但即使命令发生变化,pcduino也会收到相同的数字。

This is what its doing: 这就是它的作用:

Windows -> PCDuino Windows - > PCDuino

command = 1 -> sendBuff = 73932 command = 1 - > sendBuff = 73932

cmdstring = 1 -> n = 1 cmdstring = 1 - > n = 1


command = 1025 -> sendBuff = 73932 command = 1025 - > sendBuff = 73932

cmdstring = 1025 -> n = 4 cmdstring = 1025 - > n = 4


My windows functions are: 我的Windows功能是:

bool Client::Send(char * smsg)
{
    int iResult = send(ConnectSocket, smsg, strlen(smsg), 0);

    if (iResult == SOCKET_ERROR)
    {
        std::cout << "Sending Message has failed: " << WSAGetLastError() << "\n";
        Stop();
        return false;
    }
    return true;
}

    bool sendCommand()
{
    cmdbuffer << command;
    cmdstring = cmdbuffer.str();

    if (!client->Send((char *)cmdstring.c_str()))
    {
        std::cout << "Disconnected from Server. Press Enter to Exit";
        std::cin.ignore();
        std::cin.get();
        return false;
    }
    return true;
}

PCDuino Program PCDuino计划

/******************************************************************************/

/*Connection Globals*/
int listenfd = 0, connfd = 0;
int n;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;

/******************************************************************************/


void setup()
{

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&serv_addr, '0', sizeof(serv_addr));
    memset(sendBuff, '0', sizeof(sendBuff));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000);

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    listen(listenfd, 10);

    connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);

/******************************************************************************/


    digitalWrite(MineMode, HIGH);
}

void loop()
{
    recBuff = 0;
    deviceFlag = 0;

    //Read Socket

/******************************************************************************/

    n = read(connfd, sendBuff, strlen(sendBuff));
    recBuff = atoi(sendBuff);

/******************************************************************************/
    }

I have a printf after the read call and that's where I am getting the 73932 number. 在读取调用后我有一个printf,这就是我获得73932号码的地方。 I think I have everything you guys need but if there's anything else I need to add let me know. 我想我有你需要的一切,但如果还有什么我需要补充的让我知道。 I'm stumped...I don't know if its just a casting problem or what. 我很难过......我不知道它只是一个铸造问题还是什么。

bool Client::Send(char * smsg) bool Client :: Send(char * smsg)

you not change data here, so use const char * at least 你不是在这里改变数据,所以至少要使用const char *

send(ConnectSocket, smsg, strlen(smsg), 0) 发送(ConnectSocket,smsg,strlen(smsg),0)

If you send variable length message via TCP , you should tell somehow another side of connection how many bytes you send, for example use first 4 bytes as length 如果您通过TCP发送可变长度消息,您应该以某种方式告诉连接的另一端您发送了多少字节,例如使用前4个字节作为长度

n = read(connfd, sendBuff, strlen(sendBuff)); n = read(connfd,sendBuff,strlen(sendBuff));

you not receive any bytes here yet, so strlen(sendBuff) is useless and dangerous, you should make sure that you receive data with ending 0 byte, before call strlen. 你还没有收到任何字节,所以strlen(sendBuff)是无用且危险的,你应该确保在调用strlen之前接收结束0字节的数据。

Plus you should never assume that if you send N bytes by one chunk, you recieve N bytes on another side by one chunk, so you client should be finite state machine: 另外,你永远不应该假设如果你用一个块发送N个字节,你可以在另一个块上接收一个块的N个字节,所以你的客户端应该是有限状态机:

  1. Wait 4 bytes with length of packet (call read in loop until it return 4 bytes to you in sum). 等待4个字节的数据包长度(循环调用read ,直到它总和返回4个字节)。 Convert 4 bytes to length of message (N). 将4个字节转换为消息长度(N)。

     size_t read_bytes = 0; while (read_bytes < 4) { ssize_t n = read(); if (n < 0) handle_error(); else if (n == 0) handle_n_equal_to_0_case(); else read_bytes += n; } 
  2. Wait N bytes (call read in loop similar to (1)). 等待N个字节(类似于(1)的循环调用read )。 Not forget to use rest of bytes that you receive on step 1. 不要忘记使用在步骤1中收到的其余字节。

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

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