繁体   English   中英

将C数组初始化为自定义字符

[英]Initialize C array to custom character

我建立了一个Winsock2服务器。 该程序的一部分具有从客户端接收数据的功能。 最初,我构建的接收函数将监视传入的数据,并在允许recv()从缓冲区提取数据之前确定是否有任何其他数据要读取。 在项目开始时,此方法运行良好,但我现在正在努力提高性能。

这是我为消除对peek的使用而编写的部分代码:

    unsigned char recv_buffer[4096];
    unsigned char *pComplete_buffer = malloc(sizeof(recv_buffer) * sizeof(unsigned char*));
    int offset = 0;
    int i = 0;

    ...

    for (i; i <= sizeof(recv_buffer); i++) {
        if (recv_buffer[i] == NULL) {
            break;
        }
        pComplete_buffer[offset] = recv_buffer[i];
        offset++;
    }

    ...

这段代码可以很好地工作,但问题是NULL == 0 如果客户端恰巧发送0此循环将过早中断。 我以为我会很聪明,将数据未初始化为0xcc并使用它来确定recv_buffer的结尾,但似乎客户端有时也会将其作为其数据的一部分发送。

题:

是否可以初始化recv_buffer并可靠中断的字符?

如果没有,还有其他方法可以消除对peek的使用吗?

正确的解决方案是跟踪您开始存储在recv_buffer字节数。 sizeof()提供了缓冲区的TOTAL POSSIBLE大小,但它没有告诉您实际上有多少字节包含有效数据。

recv()告诉您返回多少字节。 recv()数据存储到recv_buffer ,使用该返回值递增定义的变量,以指示recv_buffer的有效字节recv_buffer

例如:

unsigned char recv_buffer[4096];
int num_read, recv_buffer_size = 0;

const int max_cbuffer_size = sizeof(recv_buffer) * sizeof(unsigned char*);
unsigned char *pComplete_buffer = malloc(max_cbuffer_size);

...

num_read = recv(..., recv_buffer, sizeof(recv_buffer), ...);
if (num_read <= 0) {
    // error handling...
    return;
}
recv_buffer_size = num_read;

...

int available = max_cbuffer_size - offset;
int num_to_copy = min(recv_buffer_size, available);

memcpy(pComplete_buffer + offset, recv_buffer, num_to_copy);
offset += num_to_copy;
memmove(recv_buffer, recv_buffer + num_to_copy, recv_buffer_size - num_to_copy);
recv_buffer_size -= num_to_copy;

...

是否可以初始化recv_buffer并可靠中断的字符?

不。 如果对方可以随时发送任何字符,则必须检查它们。

如果您知道发件人永远不会连续发送两个 NUL\\0\\0 ),则可以进行检查。 但是有一天,发件人将决定这样做。

如果您可以更改消息结构,那么我将首先发送消息长度(以字节为单位,取决于您的协议,网络顺序为short或int)。 然后,在解析该长度之后,接收器将确切知道要继续读取多长时间。 另外,如果您使用的是select ,它将阻塞直到有需要阅读的内容或套接字关闭(主要是-阅读文档)为止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM