[W5500] [wiz850io]
현재 ESP32와 wiz850io 모듈을 이용하여 TCP 클라이언트로 동작하고 있습니다.
PC의 TCP 서버에 접속하는데, 연결 되자마자 PC의 TCP 서버는 연결을 끊어버립니다.
이러한 과정은 Wireshark를 통해 서버가 [FIN, ACK]를 송신하는 것으로 확인하였습니다.
그런데, 서버가 왜 FIN, ACK 패킷을 송신하는지 원인을 찾지 못하였습니다.
다음은 해당 패킷의 내용을 캡쳐한 것입니다.
클라이언트[192.168.0.50]은 서버[192.168.0.101]에 접속에 성공합니다.
하지만 접속 후 클라이언트의 소켓 상태는 CLOSE_WAIT 상태로 전환합니다.
서버[192.168.0.101]가 클라이언트로 [FIN, ACK]를 보내서 그런 것으로 판단됩니다.
문제는, 왜 서버가 [FIN, ACK]를 송신하는것까요?
제가 생각할 때는 그 원인이 W5500 관련 프로그램에 있을 가능성이 많을 것으로 보고 있습니다.
클라이언트의 주요 코드는 다음과 같습니다.
어떤 부분을 검토해야 할까요?
void TCPClient_Run(unsigned char sn)
{
int32_t ret = SOCK_OK;
uint16_t size;
uint8_t * data_buf = tcp_rxdb;
uint8_t Dbg = 1;
if(App.Mode == MODE_COMM_INIT) // setup hardware configuration for TCP
{
App.time++;
if(App.time > 1000){
App.time = 0;
if(network_init() == 0)
{
ModeSet(MODE_SOCKET_CREATE);
}
}
}
else if(App.Mode == MODE_SOCKET_CREATE)
{
App.time++;
if(App.time > 1000){
App.time = 0;
printf("S%d: Open : ",sn);
ret = wiz_socket(sn, Sn_MR_TCP, App.serverport, SF_TCP_NODELAY);
if (ret < 0) {
printf("FAIL -> Close\r\n");
wiz_close(sn);
ModeSet(MODE_COMM_INIT);
}else{
printf("PASS\r\n");
//setSn_IR(sn, SOCK_INIT);
ModeSet(MODE_EXECUTE_COMM);
}
}
}
else if(App.Mode == MODE_EXECUTE_COMM)
{
tcp_status[sn] = getSn_SR(sn);
if(tcp_status_save[sn] != tcp_status[sn]){
tcp_status_save[sn] = tcp_status[sn];
App.time = 0;
printf("S%d:Status: 0x%02X\r\n",sn, tcp_status[sn]);
}
switch (tcp_status[sn])
{
// -----------------------------------------------------------------------------
case SOCK_ESTABLISHED: /* if connection is established */
// -----------------------------------------------------------------------------
App.time++;
if(App.time > 1000){
App.time = 0;
printf("S%d: SOCK_ESTABLISHED\r\n",sn);
}
if(getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
{
if(Dbg){
printf("S%d:Connected\r\n",sn);
}
setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1'
}
if ((size = getSn_RX_RSR(sn)) > 0) /* check Rx data */
{
if (size > TCP_BUF_SIZE)
size = TCP_BUF_SIZE; /* if Rx data size is lager than TX_RX_MAX_BUF_SIZE */
/* the data size to read is MAX_BUF_SIZE. */
ret = wiz_recv(sn, data_buf, size); // read the received data
if(ret <= 0){
//return ret; // If the received data length <= 0, receive failed and process end
printf("RCV Fail (%ld)\r\n", ret);
}else{
size = (uint16_t) ret;
if(Dbg){
printf("RX size: %d\r\n", size);
}
}
}
break;
// -----------------------------------------------------------------------------
case SOCK_CLOSE_WAIT: /* If the client request to close */
// -----------------------------------------------------------------------------
if(Dbg){
printf("S%d : CLOSE_WAIT -> disconnect\r\n", sn);
}
wiz_disconnect(sn);
break;
// -----------------------------------------------------------------------------
case SOCK_INIT: /* if a socket is initiated */
// -----------------------------------------------------------------------------
if(Dbg){
printf("S%d:Request to connect to the %d.%d.%d.%d : %d\r\n", sn,
Dest_Setup.destip[0], Dest_Setup.destip[1],
Dest_Setup.destip[2], Dest_Setup.destip[3], Dest_Setup.port);
}
if( (ret = wiz_connect(sn, Dest_Setup.destip, Dest_Setup.port)) != SOCK_OK){
//return ret; // Try to TCP connect to the TCP server (destination)
}
break;
// -----------------------------------------------------------------------------
case SOCK_CLOSED: /* if a socket is closed */
// -----------------------------------------------------------------------------
App.time++;
if(App.time > 4000){
App.time = 0;
}else if(App.time == 1000){
printf("\r\nS%d: 1 - Close\r\n",sn);
wiz_close(sn);
}else if(App.time == 2000){
printf("S%d: 2\r\n",sn);
}else if(App.time == 3000){
printf("S%d: 3 - socket open\r\n",sn);
if((ret=wiz_socket(sn, Sn_MR_TCP, Source_port, 0x00)) != sn){
printf("S%d: socket open FAIL\r\n",sn);
}else{
if(Dbg){
printf("S%d:Socket open PASS\r\n",sn);
}
}
}
break;
// -----------------------------------------------------------------------------
default:
// -----------------------------------------------------------------------------
break;
}
}else{
ModeSet(MODE_COMM_INIT);
}
}
다음은 printf문에 의해서 출력되는 내용입니다.
소켓의 상태가 어떤식으로 변하는지 알 수 있습니다.
S0: 1 - Close
S0: 2
S0: 3 - socket open
S0:Socket open PASS
S0:Status: 0x13
S0:Request to connect to the 192.168.0.101 : 2002
S0:Status: 0x17
S0:Connected
S0:Status: 0x1C
S0 : CLOSE_WAIT -> disconnect
S0:Status: 0x00