W5100S Send시 RST, ACK가 계속 발생합니다.

W5100S와 ATMEGA32로 펌웨어 구현중입니다.
TCP 서버 모드로 구동중이고 Hercules를 Client로 동작중인데요.

Client에서 Send를 보낼 시 서버측은 Reset되면서 Hercules에서는 "Connection refused by remote host"문구가 뜹니다…

와이어 샤크 패킷파일 첨부하였습니다. 수신은 되는것 같습니다…
확인 부탁드립니다.
//
업로드 중: [RST,ACK].PNG…
업로드 중: HERCULES.PNG…

void loopback_tcps(u_char ch /**< channel(socket) index */ )
{

//u_char * data_buf = (u_char*) TX_BUF; // 0x1100, RX_BUF = TX_BUF+TX_RX_MAX_BUF_SIZE


switch (getSn_SR(ch))
{
case SOCK_ESTABLISHED:						/* if connection is established */
	if(bchannel_start[ch]==1)
	{
                 
		bchannel_start[ch] = 2;
	}
	if ((len = getSn_RX_RSR(ch)) > 0) 			/* check Rx data */
	{
		if (len > max_bufsize) len = max_bufsize;	/* if Rx data size is lager than TX_RX_MAX_BUF_SIZE */
								/* the data size to read is MAX_BUF_SIZE. */
		len = recv(ch, data_buf, len);			/* read the received data */
                    TEST = len;
                    send(ch, data_buf, len);				/* send the received data */          
                    //send_data_processing(0, data_buf, len);
	} 
	break;
case SOCK_CLOSE_WAIT:                           		/* If the client request to close */
	disconnect(ch);
	bchannel_start[ch] = 0;
	break;
case SOCK_CLOSED:                                               /* if a socket is closed */
	if(!bchannel_start[ch]) 
	{
		bchannel_start[ch] = 1;
	}
	if(socket(ch,Sn_MR_TCP,4500,0x00) == 0)    /* reinitialize the socket */
	{
		bchannel_start[ch] = 0;
	}
	else listen(ch);
		
	
	break;
}

}


This means that at the time when packet arrives W5100S is having related socket closed, or in any other state not accepting the data from the remote host.
Connection is being established in packets 4-6, then client sends 1 character to the server (W5100S) in packet 11, it does not receive ACK, and performs keep-alive. At the time when keep-alive packet is received, socket is closed.
Why it is closed - dig into your code or put diagnostic output to see how program works and the transition of the socket state.

TCP서버쪽에서 send만 안되는것이 아니고 Receive도 안된다는 뜻인가요?? 서버에서 HEX값 38을 못받았다는 건가요??

Let’s look at the Wireshark log:
4 - client sends SYN packet to server (W5100S)
5 - server (W5100S) replies with SYN/ACK to the client, confirming it has got SYN packet
6 - client informs server (W5100S) that it has got SYN reply packet, and from now on connection is established.
11 - client sends single character to the server with push flag set, I guess this is ‘8’ which we see in the picture.

Then server does not reply with ACK packet to this ‘8’ being sent. In packet 23 client again sends one character to the server (same seq=1 ack=1 and len=1), and server replies with RST for this seq=1 and ack=1. I have no explanation why wireshark says “tcp keep-alive”, must look into the packet structure/data to see what it is about.

Therefore something wrong is happening in the server after it has connection established. Why S5100S does not reply with ACK to the packet 11 in the first place - also a good question.

Also your picture shows “connection refused by remote host”, but in wireshark log you attached connection went well, the problem happened on the data transfer.

As I said before - put diag output into your code to see how it flows, and log several connection attempts using wireshark to see several logs and probably getting the idea using more data that just one log.

Connect W5100S to your hercules PC directly. This will eliminate issues which may happen in the routing equipment. I do not say problem is there, but it seems packets are simply being lost in the wireshark output.

W5100S는 hercules PC와 직접 연결하여 테스트 하고 있습니다. wireshark값을 비교하였고 [ACK]라고 수신까지 받았습니다.
하지만 이것이 프로그램 함수를 제거하니깐 정상적으로 동작되는것? 같아요
recv함수 없이 제가 수신된 값을 읽을 수 있는 방법이 있나요?

uint16 recv(
SOCKET s, /< socket index */
uint8 * buf, /
< a pointer to copy the data to be received */
uint16 len /**< the data size to be read */
)
{
uint16 ret=0;
#ifdef DEF_IINCHIP_DBG
printf(“recv()\r\n”);
#endif

if ( len > 0 )
{
//recv_data_processing(s, buf, len);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);

/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
  ;
/* ------- */
ret = len;

}
return ret;
}

rece함수 내부의 recv_data_processing(s, buf, len);을 주석처리하니깐 RST,ACK가 발생하지 않습니다.

void recv_data_processing(SOCKET s, uint8 *data, uint16 len)
{
uint16 ptr;
ptr = IINCHIP_READ(Sn_RX_RD0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);

read_data(s, (uint8 *)ptr, data, len); // read data
ptr += len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));

}
이 함수가 잘못된 것인가요? 예제의 라이브러리입니다…

This is very good finding! If you look at the wireshark output, you see that window size decreases - to 2047 from 2048 when it received one char, and then to 2037 when it receives another 10 chars. And Ack is being advanced accordingly. This is because you commented the receive action and W5100S is having its RX buffer filled.

Now the main question - why calling this function recv_data_processing causes the issue? In my opinion, the first thing I would look at (not in your posted code) is value of len. How do you obtain it? May it have invalid, wrong value?

감사합니다. 현재는 recv시 값이 수신버퍼에 정상적으로 쌓이는것을 확인했습니다.
문제는 함수안의 코드를 변경한 것인데 동작원리를 알아야 할 것 같습니다.

if문 안에 있는데 주석되어 있는 6개가 기존 코드인데 그 부분만 변경해봤습니다.
(* Send도 마찬 가지로 Keep-alive가 발생하네요… recv처럼 변경하였지만 잘 되지 않네요, 현재 계속 디버깅 중입니다,)

void read_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len)
{
uint16 size;
uint16 src_mask;
uint8 * src_ptr;

src_mask = (uint16)src & getIINCHIP_RxMASK(s);
src_ptr = (uint8 *)(getIINCHIP_RxBASE(s) + src_mask);

if( (src_mask + len) > getIINCHIP_RxMAX(s) ) 
{
	//size = getIINCHIP_RxMAX(s) - src_mask;
	//wiz_read_buf((uint16)src_ptr, (uint8*)dst,size);
	//dst += size;
	//size = len - size;
	//src_ptr = (uint8 *)(getIINCHIP_RxBASE(s));
	//wiz_read_buf((uint16)src_ptr, (uint8*) dst,size);
         wiz_read_buf((uint16)src_ptr, (uint8*)dst,len);
} 
else
{
	wiz_read_buf((uint16)src_ptr, (uint8*)dst,len);
}

}

To understand the meaning and how code works please refer to the datasheet chapter 4. The code you commented just gets data through the boundary of the socket buffer. The RX pointers must have been managed in the wiz_read_buf() call. What I would do in this situation - display and verify all the values all the functions being called return, and check against register descriptions in datasheet to ensure there’s no misconfiguration and values are correct.