W5100 client와 연결 문제


#1

w5100을 tcp server로 사용을 하고 있습니다… pc (client)와 연결시 연결이 잘 안되는 현상이 있습니다… (spi mode 사용)

unsigned char InitSocketServer (unsigned char Socket, unsigned int Port)
{
if (socket (Socket, Sn_MR_TCP, NET_PORT, 0x20) == 0) // TCP_Socket 생성
return 0;
else
listen (Socket);

return 1;

}

void ProcessTcpServer (void)
{
unsigned int len;
unsigned int i = 0;

unsigned char data_buf[MAX_BUF_SIZE + 10];		// MAX_BUF_SIZE_100Byte..

/* Tcp Service Start */
switch (getSn_SR (nSocket))			// 총 4개의 소켓중 1번 소켓만 사용한다.
{
	case SOCK_ESTABLISHED:

		if ((len = getSn_RX_RSR (nSocket)) > 0)
		{
			if (len > MAX_BUF_SIZE) len = MAX_BUF_SIZE;

			len = recv (nSocket, data_buf, len);

			/*********************************************/
			/*			      232 처리					 */
			/*********************************************/

			for (i = 0; i < len; i++) {
				USART_Transmit (data_buf [i]);
			}
		}
		/*****************************************/
		/* 		keep alive 처리 			     */
		/*****************************************/
		if (keep_alive++ == 65000) {
			IINCHIP_WRITE (Sn_CR (nSocket), Sn_CR_SEND_KEEP);			// keep alive 는 w5100 내부적으로 처리됨 
			keep_alive = 0;												// Sn_SR 상태가 ESTABLISHED 일때만 (즉, 무조건 한바이트 수신되어야함)
		}

		break;

	case SOCK_CLOSE_WAIT:
	//case SOCK_TIME_WAIT:			// automatically changed to SOCK_CLOSED.
	//case SOCK_CLOSING:			// automatically changed to SOCK_CLOSED.
	//case SOCK_FIN_WAIT:			// automatically changed to SOCK_CLOSED.
	//case SOCK_LAST_ACK:			// automatically changed to SOCK_CLOSED.
		//disconnect (nSocket);		// by  13/12/11  - client 와 connect 문제 발생 간혹 연결이 안됨
		close (nSocket);
		break;
	case SOCK_CLOSED:				// timeout occurs & not response from remote peer.
		InitSocketServer (nSocket, NET_PORT);
		break;
}

}

위의 식으로 사용을 하고 잇는데…
테스트로 client와 connect , disconnect만 무한 반복 수행시 (300ms)
SOCK_CLOSE_WAIT 일때… disconnect (); 함수를 사용했었는데… 문제(간혹 연결 안됨)가 생겨
강제로 끊는 close();를 사용하니 잘 되던데요…

별 문제 없는 건가요?? 아니면 위의 소스보시고 잘못된 부분이 잇는지 조언부탁드립니다… 아니면 어디를 추가해야할 부분이나 수정을 해야할 부분이 있다던지… 체크좀 부탁드립니다…
w5100에서 SOCK_TIME_WAIT, SOCK_CLOSING, SOCK_FIN_WAIT, SOCK_LAST_ACK 위 4가지 상태시 데이터 시트를 보니
자동으로 automatically changed to SOCK_CLOSED. 된다해서 거기에 대한 부분은 처리를 따로 하지 않았습니다… 소스를 보시면 아시겠지만…

client와 connect, disconnect 시간이 너무 빠르면 w5100 내부적으로 못따라 오는건가요?? 조언좀 부탁드립니다… 급합니다…


#2

안녕하세요.

TCP connection을 종료 할때는 4-way hadshake 라는 매커니즘이 사용됩니다.
그렇기 때문에 disconnect하였다고 바로 종료가 되는 것이 아닙니다. 또한 일정 시간(300ms)을 기다린다고 되는 것이 아니라 close가 되기를 기다려야 합니다.

좀 더 정확한 내용은 저희 reference code의 disconnect함수를 참조 하시면 되겠습니다.

감사합니다.


#3

답변 감사드립니다… 저도 레퍼런스 코드는 참고햇습니다…
보시면 아시다시피 코드도 비슷하고요… 레퍼런스 코드에도 disconnect () 함수를 사용하고 있고요…
저도 disconnect ()함수를 사용햇었고요… 근데 간혹 연결이 안될때가 있어서요… 문제가 발생될까봐 질문을 하게 된거고요…
그럴일은 많이 없겟지만… 사용자가 일부러 client와 연결햇다가 끊었다가 계속 반복햇을시 혹시 모를 상황을 대비하기위해서…
그런 부분때문에… 질문을 하게되었습니다…
질문.1
disconnect () 함수대신 close() 함수를 사용해도 별다른 문제 없다는 말씀이신건가요??
질문.2
close가 되기를 기다려야 된다고하셧는데… 이말씀이 client에서 server (w5100)이랑 connect 되기까지 계속 연결시도를 하라는 말인건가요??


#4

안녕하세요

먼저 질문에 대한 대답을 드린다면,

질문1. 네, close해도 상관 없습니다. 다만 peer쪽에서는 상대가 close했다는 것을 알 수 없다는 문제점이 발생 하게 될겁니다.

질문2. 기다려야 된다는 의미는 status register를 보시고 SOCK_CLOSED가 될기까지 기다리라는 의미 입니다.
결과적으로는 close가 된 이후 socket을 다시 open한 후 연결이 될텐데 peer쪽에서 connect 되기까지 계속 연결시도를 해도 무방합니다. 다만 불필요한 트래픽이 발생할 수는 있습니다.

정상적인 disconnect는 4 way handshake disconnect를 거치면 W5100에서 자동으로 close가 되거나 4 way handshake 과정에서 정상적으로 FIN이나 ACK 패킷을 주고 받지 못해서 timeout이 발생하여 자동으로 close가 된 다음(status register가 SOCKE_CLOSED가 됨) 다시 소켓을 open하는 방식을 추천 드립니다.

다시 맨 처음 올리신 포스트의 질문을 보면 질문내용이 server가 client쪽으로 disconnect와 connect를 시도하는 건지 반대로 client에서 하는 건지는 명확하지 않지만,
W5100에서 disconnect명령을 내린 후 connect를 해봤자 client쪽에서 close 가 된후 재 open을 하지 않은 상태에서는 연결을 맺지 못할 수도 있고 또는 어플리케이션에 따라 SYN 패킷을 저장한 후 close이후 ACK패킷을 보내서 연결이 성립될 수도 있기 때문에 명확한 답변을 드리기 힘듭니다. 또한 OS에서 같은 포트 같은 IP address socket의 경우 close한 이후일 지라도 일정시간 점유 하고 있기 때문에 connect 실패할 경우 port번호를 변경하여 connect를 시도해야 합니다.

반대로 client쪽에서 W5100쪽으로 요청하는 것이라면, W5100이 close 된 후 재 open을 하기 전까지는 connect가 안됩니다.

감사합니다.


#5

답변 감사드립니다…
"정상적인 disconnect는 4 way handshake disconnect를 거치면 W5100에서 자동으로 close가 되거나 4 way handshake 과정에서 정상적으로 FIN이나 ACK 패킷을 주고 받지 못해서 timeout이 발생하여 자동으로 close가 된 다음(status register가 SOCKE_CLOSED가 됨) 다시 소켓을 open하는 방식을 추천 드립니다."
위처럼은 올린 소스를 보시면 알겟지만 SOCK_CLOSED시 재 OPEN하고 있고요…
그리고 Client (pc)에서 연결을 w5100(server)쪽으로 시도하는 것입니다…

그리고 RTR 과 RCR 값을 초기화 과정에서 설정을 안해주는데요… 어차피 안해줘도 default값이 설정 되는게 맞지않나요?
RTR (0x07d0) , RCT (0x08) 이값으로 설정되는게 맞지 않나요? default값으로 사용을 해도 별다른 문제 없지 않나요?
200ms / 8번


#6

안녕하세요.

RTR, RCR은 기본값으로 되었으므로 따로 설정을 안해주셔도 문제 없습니다.

간혹 연결이 안된다고 하셨는데 연결 실패가 W5100에서 open하기 전에 발생하는 것은 아닌지요??

아니면 지속적으로 연결이 안되서 W5100을 리셋해야만 되는 것인지요??

그리고 PC쪽에서 W5100으로 연결시도 할 때의 패킷을 wireshark같은 것으로 캡쳐하여 보내주시면 검토해보도록 하겠습니다.

감사합니다.