简体   繁体   English

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

[英]Initialize C array to custom character

I have built a Winsock2 server. 我建立了一个Winsock2服务器。 Part of that program has a function that receives data from clients. 该程序的一部分具有从客户端接收数据的功能。 Originally the receive function I built would peek at the incoming data and determine if there was any additional data to be read before allowing recv() to pull the data from the buffer. 最初,我构建的接收函数将监视传入的数据,并在允许recv()从缓冲区提取数据之前确定是否有任何其他数据要读取。 This worked fine in the beginning of the project but I am now working on improving performance. 在项目开始时,此方法运行良好,但我现在正在努力提高性能。

Here is a portion of the code I've written to eliminate the use of peek: 这是我为消除对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++;
    }

    ...

This code would work great but the problem is that NULL == 0 . 这段代码可以很好地工作,但问题是NULL == 0 If the client happens to send a 0 this loop will break prematurely. 如果客户端恰巧发送0此循环将过早中断。 I thought I would be clever and leave the data uninitialized to 0xcc and use that to determine the end of recv_buffer but it seems that clients sometimes send that as part of their data as well. 我以为我会很聪明,将数据未初始化为0xcc并使用它来确定recv_buffer的结尾,但似乎客户端有时也会将其作为其数据的一部分发送。

Question: 题:

Is there a character I can initialize recv_buffer to and reliably break on? 是否可以初始化recv_buffer并可靠中断的字符?

If not, is there another way I can eliminate the use of peek? 如果没有,还有其他方法可以消除对peek的使用吗?

The correct solution is to keep track of how many bytes you store in recv_buffer to begin with. 正确的解决方案是跟踪您开始存储在recv_buffer字节数。 sizeof() gives you the TOTAL POSSIBLE size of the buffer, but it does not tell you HOW MANY bytes actually contain valid data. sizeof()提供了缓冲区的TOTAL POSSIBLE大小,但它没有告诉您实际上有多少字节包含有效数据。

recv() tells you how many bytes it returns to you. recv()告诉您返回多少字节。 When you recv() data into recv_buffer , use that return value to increment a variable you define to indicate the number of valid bytes in recv_buffer . recv()数据存储到recv_buffer ,使用该返回值递增定义的变量,以指示recv_buffer的有效字节recv_buffer

For example: 例如:

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;

...

Is there a character I can initialize recv_buffer to and reliably break on? 是否可以初始化recv_buffer并可靠中断的字符?

Nope. 不。 If the other side can send any character at any time, you'll have to examine them. 如果对方可以随时发送任何字符,则必须检查它们。

If you know the sender will never send two NUL s in a row ( \\0\\0 ), you could check for that. 如果您知道发件人永远不会连续发送两个 NUL\\0\\0 ),则可以进行检查。 But then some day the sender will decide to do that. 但是有一天,发件人将决定这样做。

If you can change the message structure, I'd send the message length first (as a byte, network-ordered short or int depending on your protocol). 如果您可以更改消息结构,那么我将首先发送消息长度(以字节为单位,取决于您的协议,网络顺序为short或int)。 Then, after parsing that length, the receiver will know exactly how long to keep reading. 然后,在解析该长度之后,接收器将确切知道要继续读取多长时间。 Also if you're using select , that will block until there's something to read or the socket closes (mostly -- read the docs). 另外,如果您使用的是select ,它将阻塞直到有需要阅读的内容或套接字关闭(主要是-阅读文档)为止。

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

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