通过套接字进行数据传输[TCP]如何在c/c ++中打包多个整数并使用send()recv()传输数据? [英] Data transfer over sockets[TCP] how to pack multiple integer in c/c++ and transfer the data with send() recv()?

查看:78
本文介绍了通过套接字进行数据传输[TCP]如何在c/c ++中打包多个整数并使用send()recv()传输数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用c/c ++在linux上制作一个基于客户端/服务器的小型游戏,我需要将玩家回合发送到服务器.

I'm making a small client/server based game, on linux in c/c++ and I need to send the player turn to the server.

这是我的问题.

我想向服务器发送两个整数,有时它可以正常工作,但是有时服务器在第一个recv()中接收到两个整数,并且卡住了它.

I want to send two integers to the server and sometimes it works perfectly, but sometimes the server receives both integer in the first recv() and its stuck.

我知道最好的方法是打包消息.问题是我不知道语法的样子.

I know that the best way is to package the messages. The problem is I don't know how the syntax should look like.

从理论上讲->玩家输入就像一个int列= 4和第二个int行= 1,我将消息打包为4 | 1或类似的内容.然后,我从客户端发送到服务器,并在服务器上对其进行编码.一个例子可能很棒,或者可能会建议如何处理这样的事情.我对套接字编程还是很陌生.

这是我的函数的样子:

客户:

#define BUFFER 512

void send_turn_to_server(int sock, int row, int column)
{
   // sends  row to server from player turn

   char char_row[BUFFER];
   sprintf(char_row, "%d", row);
   char *message_from_client = char_row;
   int len, bytes_sent_row;
   len = strlen(message_from_client);

   if (sendall(sock, message_from_client, &len) == -1)
   {
      perror("sendall");
      printf("We only sent %d bytes because of the error!\n", len);
   }


   char char_column[BUFFER];
   int bytes_sent_column;
   //sends column from player turn
   //sprintf converts the int to char
   sprintf(char_column, "%d", column);
   char *column_from_client = char_column;
   len = strlen(column_from_client);

   if (sendall(sock, column_from_client, &len) == -1)
   {
      perror("sendall");
      printf("We only sent %d bytes because of the error!\n", len);
   }
   cout << "send_turn_to_server_complete" << endl;
}

在这里,我使用《 Beej网络编程指南》中的一个功能,因此可以确定整个缓冲区都已发送.

Here I use a function from Beej's Guide to Network Programming, so I can be sure the whole buffer is sent.

客户:

int sendall(int s, char *buf, int *len)
{
   int total = 0;        // how many bytes we've sent
   int bytesleft = *len; // how many we have left to send
   int n;

   while (total < *len)
   {
      n = send(s, buf + total, bytesleft, 0);
      if (n == -1)
      {
         break;
      }
      total += n;
      bytesleft -= n;
   }

   *len = total; // return number actually sent here

   return n == -1 ? -1 : 0; // return -1 on failure, 0 on success
}

服务器:

int receive_player_turn(int sock, int &int_row, int &int_column)
{
   int byte_count;
   char buf[BUFFER];
   byte_count = recv(sock, buf, sizeof buf, 0);
   cout << "The row from player: " << buf << endl;
   //The C library function int atoi(const char *str) converts the string argument str to an integer (type int).
   int_row = atoi(buf);
   //cleans the buffer
   bzero(buf, sizeof(buf));

   byte_count = recv(sock, buf, sizeof buf, 0);
   cout << buf << endl;
   cout << "The column from player: " << buf << endl;

   //converts the char string to an int
   int_column = atoi(buf);

   cout << endl

        << "receive player turn worked" << endl
        << "players turn was in the row " << int_row << " and in the column " << int_column + 1 << endl;

   return int_row, int_column;
}

从服务器正确输出:

Player connected: SchleichsSalaticus
The row from player: 7
4
The column from player: 4

receive player turn worked
players turn was in the row 7 and in the column 5  
7 4

服务器输出错误:

Player connected: SchleichsSalaticus
The row from player: 74

推荐答案

问题在于TCP是连续的,没有消息"的开始或结束的概念,因为它不是基于消息的.

The issue is that TCP is a continuous stream, with no concept of the start or end of a "message" because it is not message-based.

大多数时候,人们使用非常简单的成帧协议" ,通过这种方式,您每次传输时都会发送一个4字节的标头,告诉接收者要读取多少字节,然后发送那么多字节作为您的消息.

Most times, people use a very simple "framing protocol" whereby you always send a 4-byte header on every transfer which tells the recipient how many bytes to read, then you send that many bytes as your message.

使用 htonl()以网络字节顺序发送4字节的标头,那么您将可以互操作.此处.

Use htonl() to send the 4-byte header in network byte order then you will be interoperable. There is a very similar example here.

这篇关于通过套接字进行数据传输[TCP]如何在c/c ++中打包多个整数并使用send()recv()传输数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆