gpt4 book ai didi

c - 这个 tcp 套接字代码如何处理 rx 缓冲区?

转载 作者:太空宇宙 更新时间:2023-11-04 07:19:47 27 4
gpt4 key购买 nike

我遇到了这个 tcp 服务器示例,随 Altera Nios II 处理器一起提供,但我没有看到有关处理 rx_buffer 的部分。

server.h

typedef struct SSS_SOCKET {
enum {
READY, COMPLETE, CLOSE
} state;
int fd;
int close;
INT8U rx_buffer[SSS_RX_BUF_SIZE];
INT8U *rx_rd_pos; /* position we've read up to */
INT8U *rx_wr_pos; /* position we've written up to */
} SSSConn;

server.c

int data_used = 0, rx_code = 0;
INT8U *lf_addr;

conn->rx_rd_pos = conn->rx_buffer;
conn->rx_wr_pos = conn->rx_buffer;

printf("[sss_handle_receive] processing RX data\n");

while (conn->state != CLOSE) {
/* Find the Carriage return which marks the end of the header */
lf_addr = strchr(conn->rx_buffer, '\n');

if (lf_addr) {
/* go off and do whatever the user wanted us to do */
sss_exec_command(conn);
}
/* No newline received? Then ask the socket for data */
else {
rx_code = recv(conn->fd, conn->rx_wr_pos,
SSS_RX_BUF_SIZE - (conn->rx_wr_pos - conn->rx_buffer) -1, 0);

if (rx_code > 0) {
conn->rx_wr_pos += rx_code;

/* Zero terminate so we can use string functions */
*(conn->rx_wr_pos + 1) = 0;
}
}

/*
* When the quit command is received, update our connection state so that
* we can exit the while() loop and close the connection
*/
conn->state = conn->close ? CLOSE : READY;

/* Manage buffer */
data_used = conn->rx_rd_pos - conn->rx_buffer;
memmove(conn->rx_buffer, conn->rx_rd_pos,
conn->rx_wr_pos - conn->rx_rd_pos);
conn->rx_rd_pos = conn->rx_buffer;
conn->rx_wr_pos -= data_used;
memset(conn->rx_wr_pos, 0, data_used);
}

具体来说,我没有看到 data_used 变量的用途。 rx_rd_pos 指向 rx_buffer 并且两者似乎都没有操作,那么它们有何不同?事实上,在 Manage buffer 下似乎唯一发生的事情就是将数据复制到 rx_buffer 中。我确定我遗漏了一些简单的东西,但我似乎看不到它。

提前感谢您的帮助。

编辑:这是sss_exec_command()函数。

void sss_exec_command(SSSConn* conn) {
int bytes_to_process = conn->rx_wr_pos - conn->rx_rd_pos;
INT8U tx_buf[SSS_TX_BUF_SIZE];
INT8U *tx_wr_pos = tx_buf;

INT8U error_code;

/*
* "SSSCommand" is declared static so that the data will reside
* in the BSS segment. This is done because a pointer to the data in
* SSSCommand
* will be passed via SSSLedCommandQ to the LEDManagementTask.
* Therefore SSSCommand cannot be placed on the stack of the
* SSSSimpleSocketServerTask, since the LEDManagementTask does not
* have access to the stack of the SSSSimpleSocketServerTask.
*/
static INT32U SSSCommand;

SSSCommand = CMD_LEDS_BIT_0_TOGGLE;

while (bytes_to_process--) {
SSSCommand = toupper(*(conn->rx_rd_pos++));

if (SSSCommand >= ' ' && SSSCommand <= '~') {
tx_wr_pos += sprintf(tx_wr_pos,
"--> Simple Socket Server Command %c.\n",
(char) SSSCommand);
if (SSSCommand == CMD_QUIT) {
tx_wr_pos += sprintf(tx_wr_pos,
"Terminating connection.\n\n\r");
conn->close = 1;
} else {
error_code = OSQPost(SSSLEDCommandQ, (void *) SSSCommand);

alt_SSSErrorHandler(error_code, 0);
}
}
}

send(conn->fd, tx_buf, tx_wr_pos - tx_buf, 0);

return;

以下答案正确。我在命令函数中错过了 rx_rd 上的指针算法 :P

最佳答案

该部分在处理完数据后从缓冲区中删除数据。您发布的代码从不使用缓冲区中的数据存储,但 sss_exec_command 函数会在收到换行符后使用。该函数通过连接传递,因此无论它使用多少,它都可以增加读取位置。

数据被使用后,缓冲区管理部分回收空间。缓冲区中剩余的数据量是写入位置和读取位置之间的差值。这么多数据从写入位置移动到缓冲区的开头,然后读写指针更新到它们的新位置。读取位置设置为buffer的start,写入位置递减data_used,这是buffer的start和读指针的原始差值,即使用的数据量.

关于c - 这个 tcp 套接字代码如何处理 rx 缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22234510/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com