所以,我尝试使用 C++ 中的套接字编程在客户端和服务器之间发送数据。现在,我在 StackOverflow 中阅读了一个答案,其中提到我们必须检查每次发送时我们收到了多少原始消息,然后等到我们完全获得信息。为此,我使用了以下 sendMsg() 和 receive() 函数。
string receive()
{
string msg = "";
char last_character = '%';
do
{
char buffer[2048] = {0};
read(sockfd, buffer, 2048);
string s(buffer);
msg += s;
last_character = s[s.size() - 1];
} while (last_character != '|');
return msg.substr(0, msg.size() - 1);
}
bool sendMsg(string s)
{
s += '|';
char buffer[s.size()];
strcpy(buffer, &s[0]);
int bytes_total = 0;
int bytes_left = s.length();
int bytes_now = 0;
while (bytes_left > 0)
{
bytes_now = send(sockfd, &buffer[bytes_total], bytes_left, 0);
if (bytes_now == -1)
{
err("Error sending message");
return false;
}
assert(bytes_now <= bytes_left);
bytes_left -= bytes_now;
bytes_total += bytes_now;
}
return true;
}
这在大多数情况下工作正常,除了有时会添加一个“|”字符,即消息之前的定界符。当我将新客户端连接到服务器并尝试向客户端发送一些消息以在其控制台中打印时,这个问题就很突出。是这样的:
usernames[username] = client_socket;
comm.sendMsg(string(GRN) + "Username accepted.\n" + string(NRM));
cout << GRN << username << " connected." << NRM << endl;
comm.sendMsg(readme(username));
其中,usernames 是一个 unordered_map,它存储每个唯一用户名的 client_socket,自述函数只是一个字符串,如“欢迎来到聊天室”,+ 用户名。在这里,#define NRM“\x1B[0m”,#define GRN“\x1B[32m”
所以,我有时得到的输出是
Enter the IP address of the server: l
Connected to server.
Enter your username: user
Username accepted.
|
+------------------------------------------------------------+
| |
| [server]: Welcome to the chatroom, user |
| |
| [server]: Here are the commands you can use: |
| |
| 1. status : Lists the status of all users |
| 2. connect [username] : Connect to username to start |
| chatting |
| 3. goodbye : Ends current chatting session |
| 4. close : Disconnects the user from the |
| server |
| 5. clear : Clears the chat from the window |
| 6. Ctrl + C (client) : Disconnects the client and |
| terminates its chat session |
| if present |
| 7. Ctrl + C (server) : Terminates the server and all the|
| clients connected to the server |
+------------------------------------------------------------+
你可以注意到 |就在用户名接受行之后,这是不必要的。我无法弄清楚这个问题。 sendMsg 和 receive 功能有问题吗?或者那很好,我必须查看其余代码。客户端和服务端的文件接近700行C++代码,所以没直接贴在这里
编辑: 我将收到的功能更改如下:
string receive()
{
string msg = "";
char last_character = '%';
while (last_character != '|')
{
char buffer[2048] = {0};
int bytes_read = read(sockfd, buffer, 2048);
if (bytes_read <= 0)
{
err("Error receiving message");
return "";
}
string s(buffer, bytes_read);
msg += s;
last_character = s[s.size() - 1];
}
return msg.substr(0, msg.size() - 1);
}