2025-06-27 8:43 PM
Hi, I am using stm32f46-disco working with client for TCP server, my problem is when I start with one client it works successfully but when I connect another client (also stm32f746-disco) it receives data slower than the previous client and swaps with the first client (meaning the first client now receives data slower than the second client). Do you know this problem?
/*
* ethernet.c
*
* Created on: May 3, 2024
* Author: ACER
*/
#include "ethernet.h"
#include "../element/element.h"
#include "../user_eeprom/user_eeprom.h"
#include "lwip/tcp.h"
#include <string.h>
#include <stdarg.h>
extern struct netif gnetif;
static err_t ERROR_DEBUG; // debug
static struct tcp_pcb *user_pcb;
char CurrentState[32];
char data_server[32];
char tcp_ip[64];
static err_t user_config_server(void *arg, struct tcp_pcb *newpcb, err_t err);
static err_t user_poll_callback(void *arg, struct tcp_pcb *pcb);
static err_t user_recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static err_t user_sent_callback(void *arg, struct tcp_pcb *pcb, u16_t len);
static void return_error_mbox(err_t error);
/////////////////////////////////////////////////////////////////////////////
/*
* auto connect
*/
void auto_connect_tcp_server(void) {
char sever_ip[32] = { 0 };
char client_name[32] = { 0 };
char sever_port[32] = { 0 };
// đọc dữ liệu từ eeprom
_user_read_data_string(ADDRESS_IP, sever_ip);
_user_read_data_string(ADDRESS_NAME, client_name);
_user_read_data_string(ADDRESS_PORT, sever_port);
int count_val = 0;
uint8_t ip_val[4] = { 0 };
/* lấy địa chỉ ip của sever */
char *token = strtok(sever_ip, ".");
// Keep printing tokens while one of the
// delimiters present in str[].
while (token != NULL) {
ip_val[count_val++] = atoi(token);
token = strtok(NULL, ".");
}
if (count_val < 3) {
func_create_msbox("ip chưa được điền đầy đủ");
}
else {
// kết nối ...
connect_tcp_server(ip_val, atoi(sever_port), client_name);
}
}
/*
* connect to server
*/
uint8_t connect_tcp_server(uint8_t *ip, uint16_t port, char *name) {
// ngắt kết nối tcp
if (user_pcb != NULL) {
disconnect_tcp_server();
}
// tạo kết nối tcp
user_pcb = tcp_new();
// nhập ip sever
ip_addr_t severIP;
IP_ADDR4(&severIP, ip[0], ip[1], ip[2], ip[3]);
strcpy(tcp_ip, ipaddr_ntoa(&gnetif.ip_addr));
ERROR_DEBUG = tcp_connect(user_pcb, &severIP, port, user_config_server);
if (ERROR_DEBUG == ERR_OK) {
func_create_msbox("Kết nối thành công");
user_client_send_data("%s\r\n", name);
return 1;
}
else {
return_error_mbox(ERROR_DEBUG);
}
return 0;
}
/*
* disconnect server
*/
uint8_t disconnect_tcp_server(void) {
// ngắt kết nối tcp
tcp_arg(user_pcb, NULL); /* Xóa con trỏ dữ liệu của PCB */
tcp_sent(user_pcb, NULL); /* Xóa hàm callback khi dữ liệu được gửi */
tcp_recv(user_pcb, NULL); /* Xóa hàm callback khi dữ liệu được nhận */
ERROR_DEBUG = tcp_close(user_pcb); /* Đóng kết nối */
if (ERROR_DEBUG == ERR_OK) {
return 1;
}
else {
return_error_mbox(ERROR_DEBUG);
}
return 0;
}
/*
* send data to server
*/
void user_client_send_data(const char *str, ...) {
char buf[100];/* bien luu tru tam thoi */
va_list args;
va_start(args, str);
vsprintf(buf, str, args);
// gửi dữ liệu ra sever
ERROR_DEBUG = tcp_write(user_pcb, buf, strlen(buf), TCP_WRITE_FLAG_COPY);
if (ERROR_DEBUG == ERR_OK) {
tcp_output(user_pcb);
}
else {
return_error_mbox(ERROR_DEBUG);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/*
* config functions to tcp
*/
static err_t user_config_server(void *arg, struct tcp_pcb *newpcb, err_t err) {
/* initialize lwip tcp_poll callback function for newpcb */
tcp_poll(newpcb, user_poll_callback, 4);
/* initialize lwip tcp_recv callback function for newpcb */
tcp_recv(newpcb, user_recv_callback);
/* initialize LwIP tcp_sent callback function */
tcp_sent(newpcb, user_sent_callback);
return ERR_OK;
}
/*
* check polling event
*/
static err_t user_poll_callback(void *arg, struct tcp_pcb *pcb) {
LWIP_UNUSED_ARG(arg);
/* Kiểm tra trạng thái của kết nối */
strcpy(CurrentState, tcp_debug_state_str(pcb->state));
/* Trả về ERR_OK để báo hiệu rằng không có lỗi xảy ra */
return ERR_OK;
}
/*
* read data from server
*/
static err_t user_recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
if (p != NULL && err == ERR_OK) {
/* Xử lý dữ liệu nhận được ở đây */
memcpy(data_server, (char*) p->payload, p->tot_len);
for (int8_t i = 0; i < 32; i++) {
if (data_server[i] == '\r' || data_server[i] == '\n') data_server[i] = '\0';
}
tcp_recved(pcb, p->len);
/* Giải phóng bộ đệm pbuf */
pbuf_free(p);
}
else {
/* Xử lý khi có lỗi hoặc không có dữ liệu nhận được */
if (p != NULL) {
pbuf_free(p);
}
/* Đóng kết nối (nếu cần) */
tcp_close(pcb);
}
return ERR_OK;
}
/*
* if sending data success ...do something
*/
static err_t user_sent_callback(void *arg, struct tcp_pcb *pcb, u16_t len) {
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(len);
/* Xử lý khi dữ liệu đã được gửi đi thành công */
// blink led...
return ERR_OK;
}
/*
* return notification error
*/
static void return_error_mbox(err_t error) {
switch (error) { // debug
case ERR_MEM:
func_create_msbox("lỗi bộ nhớ");
break;
case ERR_BUF:
func_create_msbox("bộ đệm gặp sự cố");
break;
case ERR_TIMEOUT:
func_create_msbox("hết thời gian chờ");
break;
case ERR_RTE:
func_create_msbox("đường truyền gặp sự cố");
break;
case ERR_INPROGRESS:
func_create_msbox("đường truyền đang hoạt động");
break;
case ERR_VAL:
func_create_msbox("nhập sai giá trị");
break;
case ERR_WOULDBLOCK:
func_create_msbox("đường truyền đã bị chặn lại");
break;
case ERR_USE:
func_create_msbox("địa chỉ của thiết bị đã được sử dụng");
break;
case ERR_ALREADY:
func_create_msbox("đã kết nối sẵn với server");
break;
case ERR_ISCONN:
func_create_msbox("kết nối đã được thiết lập");
break;
case ERR_CONN:
func_create_msbox("không có kết nối");
break;
case ERR_IF:
func_create_msbox("Lỗi netif cấp thấp");
break;
case ERR_ABRT:
func_create_msbox("Kết nối bị hủy bỏ");
break;
case ERR_RST:
func_create_msbox("thiết lập lại kết nối");
case ERR_CLSD:
func_create_msbox("ngắt kết nối");
case ERR_ARG:
func_create_msbox("lỗi không xác định");
break;
default:
func_create_msbox("lỗi không xác định 2");
break;
}
}
//END