c - 从删除 \n 和 \0 的字符串创建协议行
问题描述
我们必须用 C 创建一个文本消息 p2p 应用程序。我们已经使用 TCP 接口完成了 p2p 连接,但是我们在实现发送和读取消息的协议时遇到了麻烦。
消息必须采用以下格式:
Line 是我们要发送和阅读的消息。消息将以 3 个字符开头以指示行的大小(例如 005)。
然后它将有我们想要写入或读取的行(例如你好)。
所以消息必须是 char t[],在本例中为 005hello。不必发送或读取 '\n' 或 '\0',只需发送或读取大小和字符串。
我们使用 read() 和 write() 调用系统使用键盘读取和写入消息,所以我们知道我们将有我们想要删除的 '\n' 和 '\0' 。
我们试图实现 2 个不能按预期工作的功能。MI_SendLine(int Socket, const char *Line) 和 MI_ReceiveLine(int Socket, const char *Line)。
MI_SendLine 必须将 *Line 转换为所描述的协议,因此行“hello”将转换为“005hello”,“hello\0\n”将转换为“005hello”,“thx for your time\n”将是“017thx 你的时间”。
对于receiveLine函数,我们也有同样的问题,所以代码就省略了。
int MI_SendLine(int Socket, const char *Line)
{
//PROTOCOL TRANSFORMATION
//3 chars reserved for size of msg
char message[3 + strlen(Line)];
int size = strlen(Line);
int j;
for(j = 2; j >= 0; j--){
message[j] = (size % 10) + '0';
if(size > 0)
size /= 10;
}
int i;
for(i = 3; i < strlen(Line) + 3; i++){
message[i] = Linia[i - 3];
}
//END PROTOCOL TRANSFORMATION
return TCP_Send(Socket, message, sizeof(message));
}
TCP 功能,已经过测试并且可以正常工作
int TCP_Sent(int Sck, const char *SeqBytes, int LongSeqBytes)
{
int bytes_written;
if((bytes_written=write(Sck,SeqBytes,LongSeqBytes))==-1){
perror("error en write");
close(Sck);
exit(-1);
}
return bytes_written;
}
我们期望“hello\n”的输出是“005hello”,但实际输出是一个充满未知字符的字符表。
示例:第一条消息:输入“aaa”收到消息“aaa?” 但它不是一个?本身,它是一个包含它的奇怪字符。
2n消息:输入“b”收到消息“b?.
第三条消息:输入“ccccc”收到消息“ccccc”但没有?
解决方案
你的代码看起来不错。垃圾必须是接收器中的错误的结果。你忘了附加一个 NUL,或者你有某种错误。
至于删除换行符,如果最后一个是换行符,只需减小大小并少复制一个字符。
int MI_SendLine(int Socket, const char *Line)
{
size_t len = strlen(Line);
if (len > 0 && Line[len-1] == '\n')
--len;
if (len > 999) {
fprintf(stderr, "Message too big!\n");
exit(1);
}
char message[3+len];
message[0] = '0' + len / 100 % 10;
message[1] = '0' + len / 10 % 10;
message[2] = '0' + len % 10;
memcpy(message+3, Line, len);
return TCP_Send(Socket, message, 3+len);
}
或者
// sprintf needs space for a NUL even if we don't send it.
char message[3+len+1];
sprintf(message, "%03d%s", len, Line);
return TCP_Send(Socket, message, 3+len);
或者
char prefix[4];
sprintf(prefix, "%03d", prefix);
return TCP_Send(Socket, prefix, 3) + TCP_Send(Socket, Line, len);
请注意,这不会检查字符串中间是否有任何换行符。
推荐阅读
- vue.js - 有没有办法在加载列表之前完全打开 v-dialog?
- c# - NuGet 更新,现在抛出 OpenTok: System.IO.FileLoadException: Could not load file or assembly JWT Version=2.0.0.0 on CreateSession
- javascript - 非法调用 window['document']['body']['append'] 函数
- jsp - Java Struts 1 HTTP 状态 500
- r - 使用另一个数据帧的行索引(条件)过滤数据帧并组合该行
- c++ - 用于 RSA PKCS#1(密钥生成)的 C++ 中的加密安全 RNG
- c - Ncurses 在不同的平台上给出不同的颜色
- tfs - 如何从 Visual Studio TFS 2019 中删除其他工作空间?
- javascript - 每次单击后更改容器中的所有 Div 颜色
- r - H2O randomForest中的多类分类