0

我目前正在使用类似 BSD 的套接字 API 进行开发。我之前问过另一个相关问题:lwip stack netconn api keep connection "keep-alive"

我现在使用以下结构:

如果建立连接,一个侦听线程会打开一个新线程:

portTASK_FUNCTION( vModbusServer, pvParameters ) {
int lSocket;
struct sockaddr_in sLocalAddr;

lSocket = lwip_socket(AF_INET, SOCK_STREAM, 0);

if (lSocket < 0) return; // check error

memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
sLocalAddr.sin_family = AF_INET;
sLocalAddr.sin_len = sizeof(sLocalAddr);
sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
sLocalAddr.sin_port = MODBUS_PORT;

if (lwip_bind(lSocket, (struct sockaddr *)&sLocalAddr, sizeof(sLocalAddr)) < 0) {
    lwip_close(lSocket);
    return;
}

if ( lwip_listen(lSocket, 20) != 0 ) {
    lwip_close(lSocket);
    return;
}

while (1) {
    vTaskDelay(1);
    int clientfd;
    struct sockaddr_in client_addr;
    int addrlen=sizeof(client_addr);

    clientfd = lwip_accept(lSocket, (struct sockaddr*)&client_addr, (socklen_t)&addrlen);
    
    if (clientfd>0) {
        sys_thread_new( "MODBUSResponder", vModbusResponder, ( void * ) &clientfd,
               lwipMODBUS_SERVER_STACK_SIZE,
               lwipMODBUS_SERVER_PRIORITY );
    }
}
lwip_close(lSocket); }

将创建此线程(响应线程):

vModbusResponder( void *pvParameters ) {
char buffer[12];
int nbytes;
int *temp = (int*) pvParameters;
int clientfd = *temp;

do {
    nbytes=lwip_recv(clientfd, buffer, sizeof(buffer),0);
    if (nbytes>0) { //no error

    }
}  while (nbytes>0);
lwip_close(clientfd);
vTaskDelete(NULL); }

这适用于两个连接(两个响应线程),例如与嵌入式设备连接的两台 PC,但如果我尝试与第三台 PC 连接,则它会断开第一个连接。我不明白为什么会这样。使用 RST 从嵌入式设备 (lwip) 断开连接。如果我连接第四台 PC,第二个连接将断开。

我尝试了以下事情:

将此行编辑为:

定义 SYS_THREAD_MAX 30

有人可以给一些提示吗?我有什么问题吗?

4

1 回答 1

1

我找到了解决方案:我没有编辑以下配置:

#define MEMP_NUM_TCP_PCB        2 // I edited this to 5
#define MEMP_NUM_NETBUF         3 // I edited this to 5
#define MEMP_NUM_NETCONN        4 // I edited this to 5

现在我可以同时建立 5 个 TCP 连接。如果我尝试打开第 6 个连接,那么它将发送一个 RST。

@乔尔坎宁安:

你是什​​么意思“但是你传递clientfd的方式是不安全的。不能保证你的分叉线程会在执行返回到原始线程之前运行并尊重pvParameter(这将在下一次重新分配clientfd调用accept())”RTOS会在打开TCP连接之前切换回监听套接字吗?防止这种情况发生的最好方法是什么?给它比监听套接字更高的优先级?

于 2015-05-15T19:28:24.947 回答