TCP Server/Client Mode 문의


#1

안녕하십니까
Wiznet w5100 Module를 사용 중입니다.
MCU는 STM32를 사용 하며 IAR 6.5를 사용 하고 있습니다.
메인에서는 틱이 돌때마다 ProcessTcpSever를 호출 하고 있습니다.

첫번째로
테스트 프로그램은 TCP Client Mode로 Send 시,
Connect -> send -> close
루프를 30번 동작 합니다.
초기 1번은 성공을 하며, close 후, 바로 connect 요청을하여
send를 할경우 connect fail이 뜨게 됩니다.

테스트 프로그램 로그입니다.
Connect Ok…
Send Ok…
Receive Ok…
Connect Fail…

MCU Log 입니다.
data ok
==============>[SOCK_ESTABLISHED]
==============>[SOCK_CLOSE_WAIT]
==============>[listen]

이후 connect가 안됩니다.

두번째로,
테스트 프로그램을
Connect
31번 루프 send
close
처음 커넥트를 하고 send루프를 30번 하고 close를 할 경우에는
정상적으로 동작을 합니다.

첫번째 방법으로 TCP를 사용 하려 한다면 소스 수정이 필요한 부분이 있는가요?
답변을 달아주실때 유선이 가능 하시면 통화좀 부탁드립니다.
010-6391-0375 입니다.

void ProcessTcpSever(int16u _port)
{
int8u s = eTCP_SERVER_SOCKET;
int8u sstate = getSn_SR(s);

switch (sstate)
{
// Socket CLOSED일 경우      
case SOCK_CLOSED:
	if(!m_SokStatus2)m_SokStatus2 = 1;
	//socket 초기화 하고
	if(socket(s,Sn_MR_TCP, _port,0x00) == 0)
	{
		logE("Fail to create socket.");
		m_SokStatus2 = 0;
	}
	else
	{
		//접속대기
		listen(s);
	}
break; 


case SOCK_ESTABLISHED:
//수신데이터가 있으면
		int rcvLen = getSn_RX_RSR(s);
		if(0 < rcvLen)onServerRcvData(rcvLen,s);
break;
case SOCK_CLOSE_WAIT:                             
//If the client request to close
	disconnect(s);
	m_SokStatus2 = 0;
break;  

default:
break;
}  

}


#2

안녕하세요.

TCP의 경우 disconnect를 할 경우 4 way handshake 과정을 거치게 됩니다. 즉, FIN packet과 ACK를 주고 받아야지 close상태로 바뀝니다. 그래서 제 생각에는 client에서 close(단순 close가 아니라 disconnect일 경우)한 후 바로 connect 요청시 연결이 안되는 것으로 판단됩니다. 정확한 것은 wireshark같은 패킷캡쳐 프로그램으로 분석해 보시면 될 겁니다.

즉, CLOSE_WAIT 상태에서 빠져나와 listen상태로 가기 전에 connect 요청을 보내서 fail이 난것이 아닐까 생각 됩니다.

빠른 close를 원하신다면 상대방에서 disconnect요청이 들어 왔을 경우 disconnect가 아니라 바로 close 이후 약 10ms딜레이를 준다음 socket을 재 open 해도 무방합니다만, CLOSE_WAIT상태는 half close상태로 상대방이 보낸 패킷이 있다면 이를 모두 처리한 이후에 close를 하게 됩니다. 이 과정이 필요 없으시다면 close를 해도 됩니다.

감사합니다.