WIZnet Developer Forum

Wiz550io 동작 관련 두번째 질문 입니다

저번 질문에 대답이 없어서.
혼자 열공 하다 보니깐. LOOPBACK 동작이 되더라구여.
PC와 1:1 통신 구성했습니다.
1)Wiz550io Server, PC client 동작은 하구여
2) Wiz550io client, PC Server 동작은 안해서 질문을 드립니다.
LOOPBACK connect 함수에서 TIMEOUT으로 빠져 나오거든여.
IP는 ping test로 동작 하는것 확인 했구여.
무엇이 문제 일까여.

  1. Wiz550io client, PC Server 동작은 안해서 질문을 드립니다.
    LOOPBACK connect 함수에서 TIMEOUT으로 빠져 나오거든여.
    IP는 ping test로 동작 하는것 확인 했구여.
    무엇이 문제 일까여.

=> ping test가 정상동작인 것으로 보아 Connect시 ARP Time-out에 의해 Time-out이 발생하는 것 갖지는 않습니다.
PC쪽에 서버의 Port number혹은
방화벽쪽을 살펴보시기 바랍니다.
감사합니다.

Wiz550io와 노트북과 1:1 통신을 하고 있거든여.
방화벽 문제는 아닌거 같네여.
노트북과 데스크탑으로 hercules로 TCP 동작을 하면 정상 동작 합니다.
프로그램은 다음과 같습니다.
while(1)
{
loopback_tcpc(4, 5000);
}
///////////////////////////////////////////////////////////////
void loopback_tcpc(SOCKET s, uint16 port)
{
uint16 RSR_len;
uint16 received_len;
uint8 * data_buf = TX_BUF;
uint8_t ret;

ret = getSn_SR(s);

switch (ret)
{
case SOCK_ESTABLISHED: /* if connection is established */
printf("\r\n%d : SOCK_ESTABLISHED", s);

  if(ch_status[s]==1)
  {
     printf("\r\n%d : Connected",s);
     ch_status[s] = 2;
  }

  if ((RSR_len = getSn_RX_RSR(s)) > 0)         /* check Rx data */
  {
     if (RSR_len > TX_RX_MAX_BUF_SIZE) RSR_len = TX_RX_MAX_BUF_SIZE;   /* if Rx data size is lager than TX_RX_MAX_BUF_SIZE */
                                                                        /* the data size to read is MAX_BUF_SIZE. */
     received_len = recv(s, data_buf, RSR_len);         /* read the received data */
     send(s, data_buf, received_len, (bool)0);         /* sent the received data */
  }

  break;

case SOCK_CLOSE_WAIT: /* If the client request to close /
printf("\r\n%d : CLOSE_WAIT", s);
if ((RSR_len = getSn_RX_RSR(s)) > 0) /
check Rx data /
{
if (RSR_len > TX_RX_MAX_BUF_SIZE) RSR_len = TX_RX_MAX_BUF_SIZE; /
if Rx data size is lager than TX_RX_MAX_BUF_SIZE /
/
the data size to read is MAX_BUF_SIZE. /
received_len = recv(s, data_buf, RSR_len); /
read the received data /
}
disconnect(s);
ch_status[s] = 0;
break;
case SOCK_CLOSED: /
if a socket is closed /
if(!ch_status[s])
{
printf("\r\n%d : Loop-Back TCP Client Started. port: %d", s, port);
ch_status[s] = 1;
}
if(socket(s, Sn_MR_TCP, any_port++, 0x00) == 0) /
reinitialize the socket /
{
printf("\a%d : Fail to create socket.",s);
ch_status[s] = 0;
}
break;
case SOCK_INIT: /
if a socket is initiated */

            if(timer_dec[MAIN_TIMER] == 0)
            {
                    connect(s, Chconfig_Type_Def.destip, Chconfig_Type_Def.port); /* Try to connect to TCP server(Socket, DestIP, DestPort) */
                    timer_dec[MAIN_TIMER] = 2*3000;

                    printf("\n\rSOCK_INIT %d,%d,%d,%d port =%d  ",Chconfig_Type_Def.destip[0],Chconfig_Type_Def.destip[1],Chconfig_Type_Def.destip[2],Chconfig_Type_Def.destip[3],Chconfig_Type_Def.port);
            }

            break;
    default:
            break;
    }

}
//////////////////////////////////////////////////////////////////////
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{
uint8 ret;
if
(
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
(port == 0x00)
)
{
ret = 0;
}
else
{
ret = 1;

    // set destination IP
    IINCHIP_WRITE( Sn_DIPR0(s), addr[0]);
    IINCHIP_WRITE( Sn_DIPR1(s), addr[1]);
    IINCHIP_WRITE( Sn_DIPR2(s), addr[2]);
    IINCHIP_WRITE( Sn_DIPR3(s), addr[3]);
    IINCHIP_WRITE( Sn_DPORT0(s), (uint8)((port & 0xff00) >> 8));
    IINCHIP_WRITE( Sn_DPORT1(s), (uint8)(port & 0x00ff));
    IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CONNECT);
    /* wait for completion */
    while ( IINCHIP_READ(Sn_CR(s) ) ) ;

    while ( IINCHIP_READ(Sn_SR(s)) != SOCK_SYNSENT )
    {
        if(IINCHIP_READ(Sn_SR(s)) == SOCK_ESTABLISHED)
        {
            break;
        }
        if (getSn_IR(s) & Sn_IR_TIMEOUT)
        {
            IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT));  // clear TIMEOUT Interrupt
            ret = 0;
        printf("Sn_IR_TIMEOUT  \n\r");
            break;
        }
    }
}

return ret;
}

아래 소스는 정상적으로 잘 작동하는 LOOPBACK 예제입니다 참고하세요~ :slight_smile:

#if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK

int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
{
int32_t ret;
uint16_t size = 0, sentsize=0;

#ifdef LOOPBACK_DEBUG
uint8_t destip[4];
uint16_t destport;
#endif

switch(getSn_SR(sn))
{
case SOCK_ESTABLISHED :
if(getSn_IR(sn) & Sn_IR_CON)
{
#ifdef LOOPBACK_DEBUG
getSn_DIPR(sn, destip);
destport = getSn_DPORT(sn);

		printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);

#endif
setSn_IR(sn,Sn_IR_CON);
}
if((size = getSn_RX_RSR(sn)) > 0) // Don’t need to check SOCKERR_BUSY because it doesn’t not occur.
{
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
ret = recv(sn, buf, size);

		if(ret <= 0) return ret;      // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
		sentsize = 0;

		while(size != sentsize)
		{
			ret = send(sn, buf+sentsize, size-sentsize);
			if(ret < 0)
			{
				close(sn);
				return ret;
			}
			sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
		}
     }
     break;
  case SOCK_CLOSE_WAIT :

#ifdef LOOPBACK_DEBUG
//printf("%d:CloseWait\r\n",sn);
#endif
if((ret = disconnect(sn)) != SOCK_OK) return ret;
#ifdef LOOPBACK_DEBUG
printf("%d:Socket Closed\r\n", sn);
#endif
break;
case SOCK_INIT :
#ifdef LOOPBACK_DEBUG
printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port);
#endif
if( (ret = listen(sn)) != SOCK_OK) return ret;
break;
case SOCK_CLOSED:
#ifdef LOOPBACK_DEBUG
//printf("%d:TCP server loopback start\r\n",sn);
#endif
if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;
#ifdef LOOPBACK_DEBUG
//printf("%d:Socket opened\r\n",sn);
#endif
break;
default:
break;
}
return 1;
}

int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport)
{
int32_t ret; // return value for SOCK_ERRORs
uint16_t size = 0, sentsize=0;

// Destination (TCP Server) IP info (will be connected)
// >> loopback_tcpc() function parameter
// >> Ex)
// uint8_t destip[4] = {192, 168, 0, 214};
// uint16_t destport = 5000;

// Port number for TCP client (will be increased)
uint16_t any_port = 50000;

// Socket Status Transitions
// Check the W5500 Socket n status register (Sn_SR, The ‘Sn_SR’ controlled by Sn_CR command or Packet send/recv status)
switch(getSn_SR(sn))
{
case SOCK_ESTABLISHED :
if(getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
{
#ifdef LOOPBACK_DEBUG
printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
#endif
setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to ‘1’
}

     //////////////////////////////////////////////////////////////////////////////////////////////
     // Data Transaction Parts; Handle the [data receive and send] process
     //////////////////////////////////////////////////////////////////////////////////////////////
	 if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
     {
		if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
		ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)

		if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end
		sentsize = 0;

		// Data sentsize control
		while(size != sentsize)
		{
			ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
			if(ret < 0) // Send Error occurred (sent data length < 0)
			{
				close(sn); // socket close
				return ret;
			}
			sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
		}
     }
	 //////////////////////////////////////////////////////////////////////////////////////////////
     break;

  case SOCK_CLOSE_WAIT :

#ifdef LOOPBACK_DEBUG
//printf("%d:CloseWait\r\n",sn);
#endif
if((ret=disconnect(sn)) != SOCK_OK) return ret;
#ifdef LOOPBACK_DEBUG
printf("%d:Socket Closed\r\n", sn);
#endif
break;

  case SOCK_INIT :

#ifdef LOOPBACK_DEBUG
printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
#endif
if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination)
break;

  case SOCK_CLOSED:
	  close(sn);
	  if((ret=socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn) return ret; // TCP socket open with 'any_port' port number

#ifdef LOOPBACK_DEBUG
//printf("%d:TCP client loopback start\r\n",sn);
//printf("%d:Socket opened\r\n",sn);
#endif
break;
default:
break;
}
return 1;
}

int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port)
{
int32_t ret;
uint16_t size, sentsize;
uint8_t destip[4];
uint16_t destport;

switch(getSn_SR(sn))
{
case SOCK_UDP :
if((size = getSn_RX_RSR(sn)) > 0)
{
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);
if(ret <= 0)
{
#ifdef LOOPBACK_DEBUG
printf("%d: recvfrom error. %ld\r\n",sn,ret);
#endif
return ret;
}
size = (uint16_t) ret;
sentsize = 0;
while(sentsize != size)
{
ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport);
if(ret < 0)
{
#ifdef LOOPBACK_DEBUG
printf("%d: sendto error. %ld\r\n",sn,ret);
#endif
return ret;
}
sentsize += ret; // Don’t care SOCKERR_BUSY, because it is zero.
}
}
break;
case SOCK_CLOSED:
#ifdef LOOPBACK_DEBUG
//printf("%d:UDP loopback start\r\n",sn);
#endif
if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn)
return ret;
#ifdef LOOPBACK_DEBUG
printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port);
#endif
break;
default :
break;
}
return 1;
}

#endif

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.