如何在 c++ 中通过套接字编写多行
How to write multiple lines over a socket in c++
套接字编程的新手,只是一个简短的问题,我正在尝试从服务器在我的客户端上显示多行输出,但我似乎无法让这些行分开。任何帮助表示赞赏。
服务器:
void help(int sock)
{
n = write(sock,"Commands:n",11);
n = write(sock,"HELP -> Displays usable commandsn",34);
n = write(sock,"BROADCAST 'message' -> Sends 'message' to every usern",54);
n = write(sock,"SEND 'user' 'message' -> Sends 'message' to 'user'n",52);
n = write(sock,"DISPLAY -> Displays all current usersn",39);
n = write(sock,"LEAVE -> Ends the current sessionn",35);
}
客户:
while(buffer[0] != 'L')
{
bzero(buffer,256);
n = read(sockfd,buffer,255);
cout << buffer << "n";
}
您的代码存在三个问题:
-
对
write()
的调用包括字符串的 null 终止符。 在这种情况下,你不应该那样。 -
您的
read()
代码忽略了read()
的返回值。仅仅因为您要求 255 字节并不能保证您将收到 255 字节。 返回值告诉您实际接收了多少字节。 而且你收到的字节也不能保证以空结尾,所以你不能将缓冲区单独作为普通char*
指针写入std::cout
,这将使它寻找一个空终止符。std::cout
有一个write()
方法,可用于指定要写入的char
数。 为此,请使用read()
的返回值。 -
除此之外,您假设对
read()
的调用将读取单个完整行,以便您可以检查最后一个收到的缓冲区中的第一个char
,以了解最后一行LEAVE
的L
。 这根本不是真的,你不能依赖它。 TCP 是一个字节流,read()
将接收和返回任意数量的数据,具体取决于套接字接收缓冲区中的可用数据。 如果需要读取基于行的数据,则必须将输入字节累积到某种不断增长的缓冲区中,然后在新数据到达时扫描该缓冲区以查找换行符。 然后,您可以从该缓冲区中仅删除已完成的行,并根据需要处理其内容。
尝试更多类似的东西:
int writestr(int sock, const char *str)
{
int n, len = strlen(str);
while (len > 0)
{
n = write(sock, str, len);
if (n < 0) return n;
str += n;
len -= n;
}
return 0;
}
void help(int sock)
{
n = writestr(sock, "Commands:n");
n = writestr(sock, "HELP -> Displays usable commandsn");
n = writestr(sock, "BROADCAST 'message' -> Sends 'message' to every usern");
n = writestr(sock, "SEND 'user' 'message' -> Sends 'message' to 'user'n");
n = writestr(sock, "DISPLAY -> Displays all current usersn");
n = writestr(sock, "LEAVE -> Ends the current sessionn");
}
char buffer[256];
std::string data;
std::string::size_type pos, last_pos = 0;
while (true)
{
n = read(sockfd, buffer, sizeof(buffer));
if (n <= 0) break;
std::cout.write(buffer, n);
data.append(buffer, n);
pos = data.find('n', last_pos);
if (pos != std::string::npos)
{
std::string line = data.substr(0, pos);
/* if you want to support CRLF line breaks, do this instead:
std::string::size_type len = pos;
if ((len > 0) && (data[len-1] == 'r'))
--len;
std::string line = data.substr(0, len);
*/
data.erase(0, pos+1);
if (line.compare(0, 5, "LEAVE") == 0)
break;
last_pos = 0;
}
else
last_pos = data.size();
}
相关文章:
- 当套接字连接断开时检测C/C++Unix
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- 套接字读取后,我在缓冲区中看到意外输入
- 如何在CPP中创建应该在Windows和Linux上运行的套接字?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 套接字连接"Operation not permitted"错误,甚至使用升压/平发器根.cpp
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- (Winsock) UDP 接收工作正常,但同一套接字的发送失败
- MSG_WAITALL的套接字发送得到了 22 EINVAL
- C++套接字客户端到 Python 服务器未创建连接
- 在不知道套接字的情况下关闭网络连接
- C++套接字对不读/写父/子
- 非更新套接字消息
- SIGSEGV on Boost UDP 套接字关闭 - tcache_get at malloc.c.
- 将"uint8_t"(从套接字读取)隐式转换为"char"安全吗
- 当对套接字 send() 的同步调用由于连接另一端丢失而被阻止时,如何恢复?
- 当客户端在 write() 期间终止连接时,由对等套接字错误重置连接
- 了解是否接受套接字