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

时间:2016-05-09 01:23:50

标签: c++ tcp

我正在研究一个由连接到Windows计算机的xbox控制器控制的机器人,并通过tcp连接将命令发送到pcduino。我通过发送1和0的字符串来告诉pcduino打开哪些电机。我试图通过发送一个int并使用位掩码来对pcduino做出决定来优化它,但我不能让pcduino正确地接收int。我测试了windows函数发送带有sokit的命令并发送了正确的值,但即使命令发生变化,pcduino也会收到相同的数字。

这就是它的作用:

Windows - > PCDuino

command = 1 - > sendBuff = 73932

cmdstring = 1 - > n = 1

command = 1025 - > sendBuff = 73932

cmdstring = 1025 - > n = 4

我的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计划

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

/*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);

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

我在读取调用后有一个printf,这就是我获得73932号码的地方。我想我有你需要的一切,但如果还有什么我需要补充的让我知道。我很难过......我不知道它只是一个铸造问题还是什么。

1 个答案:

答案 0 :(得分:0)

  

bool Client :: Send(char * smsg)

您不在此处更改数据,因此请至少使用const char *

  

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

如果你通过TCP发送可变长度的消息,你应该知道 不知怎的,连接的另一面你发送了多少字节, 例如,使用前4个字节作为长度

  

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

你还没有在这里收到任何字节,所以strlen(sendBuff)是无用且危险的, 你应该确保收到之前结束0字节的数据 打电话给strlen。

另外,你永远不应该假设如果你用一个块发送N个字节, 你在另一边收到一个块的N个字节, 所以你的客户端应该是有限状态机:

  1. 等待包含长度的4个字节(在循环中调用read,直到它总和返回4个字节)。将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. 等待N个字节(在循环中调用read,类似于(1))。不要忘记使用在步骤1中收到的其余字节。