1.STM32芯片,tcp服務器,網線連接時候,客戶端不斷重連可以正常穩定連接。
2.客戶端不斷重連時候,網線不斷斷開重連,最後客戶端連不上,甚至程序直接死機。
通過仿真發現err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err),客戶端申請連接pcb = NULL,也就是說沒有空餘的pcb給重連客戶端使用,直接仿真tcp_active_pcbs信息發現,pcb->state = FIN_WAIT_1 || FIN_WAIT_2。網線不斷斷開,pcb關閉4次握手沒有實現,只進行一部分,一直等待中。
更改lwip源碼不知重哪裏下手,也怕改錯出現更多bug,只能取巧弄下。
在err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err)函數最前面加個判斷,客戶端連接分配的pcb爲空閒(全被佔用了),找到等待關閉pcb全釋放了(可能會出現其他問題,不過我這只是單對單使用,能重連上就行)。
if(pcb == NULL){
/*網絡不穩(不斷插拔網線),強制釋放pcb*/
tcp_find_waitPcb();
printf("MBtcp: accept pcb == NULL\r\n");
return ERR_ARG;
}
tcp_find_waitPcb()的函數定義:
void tcp_find_distant(void)
{
struct tcp_pcb *pcb = NULL;
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
{
if(pcb->state == FIN_WAIT_1 || pcb->state == FIN_WAIT_2){
tcp_abort( pcb );
}
}
}
3.網線穩定,但是客戶端不斷快速斷開連接,出現pcb = pcb->next,進入void tcp_slowtmr(void)函數死循環中出不來了。
參照:http://www.51hei.com/bbs/dpj-140158-1.html 完美解決問題
需改內容 |
解釋
|
|
文件名稱
|
添加內容(增加紅色字體)
|
|
tcp.h
|
/* the TCP protocol control block */
struct tcp_pcb {
..............................略......................................
u8_t pcb_used;
};
|
在struct tcp_pcb 結構體中增加一個字段,pcb_used。這個字段值 = 0 或 = 1。
0代表這個TCP_PCB塊沒有在使用,已經釋放。
1代表這個TCP_PCB塊正在使用,佔用內存。
|
memp.c
|
void memp_free(memp_t type, void *mem)
{struct memp *memp; struct tcp_pcb *pcb;
if(type == MEMP_TCP_PCB ){
pcb = (struct tcp_pcb *)mem;
if(pcb->pcb_used == 0){
return;
}
pcb->pcb_used = 0;
}
SYS_ARCH_DECL_PROTECT(old_level);
............................略......................................
}
|
在釋放TCP_PCB塊的時候,如果pcb_used==0,那麼這個TCP_PCB塊已經釋放過了,可能是沒連接的塊系統自己釋放,也能是自己誤操作,多次釋放。總之,不管什麼原因,已經釋放過的不能再釋放了,所有這邊直接return退出。沒有釋放的正常釋放,只是字段pcb_used置0。
|
tcp.c
|
struct tcp_pcb * tcp_alloc(u8_t prio)
{ ....................略.....................................
if (pcb != NULL) {
......................略......................................
pcb->pcb_used = 1;
}
return pcb;
}
|