我有一个我正在处理的服务器 - 客户端应用程序,它基本上模拟了一个聊天室。这是学校的一项任务,协议规范有些严格。
我有一个char数组,它将存储来自客户端的所有消息。
客户端必须首先将消息的长度作为uint8_t发送,然后将消息本身作为char数组发送。
我的问题是我需要存储在发送实际消息之前发送的uint8_t值,但我只能使用消息数组来存储来自客户端的任何信息。
如果我没弄错的话,char数组将不会存储被发送的uint8_t,除非我以某种方式投射它。
如何将uint8_t转换为字符并返回uint8_t?
我在这里尝试寻找类似的问题,但找不到一个例子。
server.c
uint8_t length = 21;
char clients_message[] = "Hi how are you today?";
send(servers_sd, &length, sizeof(length), 0);
send(serers_sd, &clients_message, sizeof(clients_message), 0);
client.c
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
int main(){
char s[20],*list[196][20];
int i;
FILE *lista;
lista=fopen("lista.txt","r");
i=0;
while(feof==0){
getline(list[i],0,lista);
i=i+1;
printf("%s\n",list[i]);
}
for(i=0;i<195;i++){
//printf("%s\n",list[i]);
}
fclose(lista);
}
答案 0 :(得分:3)
如果您使用uint8_t
为typedef
到unsigned char
(您很可能是)的架构,那么只需先取char
并将其投放到uint8_t
:
length = (uint8_t)(message_received[0]);
它应该工作。
答案 1 :(得分:1)
char
正好是一个字节(根据C标准的定义)。除非字节在您的系统上不是8位(这样的系统存在,但我敢打赌,您从未使用过或甚至没有使用过),uint8_t
和char
的数据类型完全相同。
char c = 5;
uint8_t u = c;
如果您可以使用数据类型执行类似的操作,那么您可以根据需要在这两种数据类型之间转换指针:
char c[] = { 'H', 'e', 'l', 'l', 'o' };
uint8_t * u = (uint8_t *)c;
uint8_t x = u[1];
// x is 101, which is the ASCII char code of 'e'
实际上你甚至可以用字符串来做,因为字符串也只是一个字符数组,只有一个NUL
终止。
char * c = "Hello";
// "Hello" is in fact just { 'H', 'e', 'l', 'l', 'o', '\0' }
uint8_t * u = (uint8_t *)c;
uint8_t x = u[1];
// x is 101, which is the ASCII char code of 'e'
唯一需要注意的是C标准没有定义char
是签名还是未签名。与默认情况下签名的整数类型不同,如果您请求的话,只有无符号整数类型(例如long
vs unsigned long
),默认情况下char
可能是有符号或无符号的。因此,如果您需要其中任何一个,则必须使用signed char
或unsigned char
作为数据类型。在实践中,除非您对char
值执行某些数学或逻辑运算(在现代C代码中您可能不应该这样做),否则它不起作用。
由于你的消息不可能大于256个字符(否则长度不适合uint8_t
)并且长度总是恰好一个字节,我会编写如下代码:
uint8_t messageLength = 0;
ssize_t bytesRead = recv(clients_sd, &messageLength, 1, 0);
if (bytesRead == -1) {
// Handle read error
}
if (bytesRead == 0) {
// Handle end of stream
}
char message[256];
bytesRead = recv(clients_sd, message, messageLength, 0);
if (bytesRead == -1) {
// Handle read error
}
if (bytesRead == 0) {
// Handle end of stream
}
if (bytesRead < messageLength) {
// Handle truncated message (message too small)
}
再一次,显然有些人已经不理解我的第二句了:我在假设之上写的所有东西,系统上的字节都是8位长。这段代码不能移植到字节多于或少于8位的平台,这已经是我的第二句明确指出的,但这并没有使我的回复错误。如果不允许编写不可移植到地球上所有现有平台的C代码,则将禁止所有现有C代码的90%。您知道您正在使用的平台,并且您知道您使用应用程序定位的平台,因此您有责任确保所有这些平台的代码都正确。
答案 2 :(得分:0)
char可以很容易地转换为uint8_t,但我不明白你为什么需要在消息数组中存储长度。为什么不能只存储在变量中?
这里是您的客户端和服务器示例,我认为这些更改很有帮助:
server.c
uint8_t len; /* store the length of the message here */
recv(clients_sd, &len, sizeof(len), 0);
char message_received[len];
recv(clients_sd, message_received, len, 0); /* get and store the message here */
client.c
uint8_t length = 21;
char clients_message[] = "Hi how are you today?";
send(servers_sd, &length, sizeof(length), 0);
send(serers_sd, clients_message, length, 0);