---
title: "보드 하나에 W5500 2개를 이용 내부, 외부 통신"
url: "https://maker.wiznet.io/forum/12961"
markdown_url: "https://maker.wiznet.io/forum/12961/md"
type: "Forum topic"
category: "Ethernet Chips"
author: "PSS"
created: "2018-06-24T23:41:28+09:00"
last_activity: "2018-07-09T07:26:08+09:00"
language: "ko"
views: 3080
replies: 48
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# 보드 하나에 W5500 2개를 이용 내부, 외부 통신

## Question

Asked by PSS on 2018-06-24 in Ethernet Chips.

보드 하나에 W5500 2개를 이용 내부, 외부 통신 할 생각입니다.
내부는 UDP 로 할 생각이며 외부는 TCP로 할 생각입니다. 소스 작성은 했고 동작은 10ms 마다 TCP-> UDP 번갈아 가면서 통신을 할 생각으로 작성을 하였습니다.
아래 소스 입니다.

---------main----

```
InitUserSpiDrvA();      // SPI_seta SPI 레지스터 설정
InitUserSpiDrvB();      // SPI_setb SPI 레지스터 설정

InitUserEthernetDrvA(); // w5500 init_buffer_A  위즈넷 CS ,read, write 함수 리콜 설정 및 IP설정
//InitUserEthernetDrvB(); // w5500 init_buffer_b UDP  위즈넷 CS ,read, write 함수 리콜 설

InitCommManager(ID_Check, CNTER_0, CNTER_1, CNTER_2, CNTER_3); UDP IP 설정

if(TimeTask.bit.Task_10ms==TRUE)
	{
	  tick_10msA++;
     switch(tick_10msA){

        case 1:
            reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSA, SpiDrv_Disable_CSA);
            reg_wizchip_spi_cbfunc(SpiDrv_ReadA, SpiDrv_WriteA);
            SOCK_ESTABLISHEDA=EthernetDrv_TcpSvSockOpen(0,5000); 소켓 설정
            ChkPhyLinkA=EthernetDrv_TcpTxByte(0,0x01); //send 0x01 
            break;
        case 2:
            reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSB, SpiDrv_Disable_CSB);
            reg_wizchip_spi_cbfunc(SpiDrv_ReadB, SpiDrv_WriteB);
            ChkComm_iNet(); UDP 소켓 설정 및 IP설정 , send 데이터 
            tick_10msA=0;
            break;
       }
```

이렇게 하면 TCP 먼저실행을 하는데 소켓 연결이 되면 계속 데이터가 보내집니다. 하지만
10ms 지나 udp로 가서 소켓을 만들고 데이터를 보내야 하는데 그러질 못하고 TCP에서만 데이터가 보내집니다.

이런 방법이 아닌 다른 방법이 있나요 ?

## Replies

### Reply 1 by lawrence, 2018-06-25

안녕하세요 위즈네트 입니다.

작성해주신 내용 확인했습니다.

일단 해당 내용만 보고는 판단하기가 어려워서 몇가지 확인하실 수 있는 부분에 대해서 답변드립니다.

첫번째로 일단 case 2로 들어오는지가 확인되셨는지요?

두번째로 들어왔다면 인터페이스쪽에서 동작하지 않는것인지요?

세번째로 인터페이스가 동작한다면 ChkComm_iNet(); 함수내에서 동작하지 않는지요?

다음의 내용을 검토하시고 디버깅을 부탁드립니다.

감사합니다.

### Reply 2 by PSS, 2018-06-25 (in reply to reply 1)

이제 보니 TCP/IP , UDP 둘다 됩니다.

한가지 여줘 보고 싶은건
while(1){
reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSB, SpiDrv_Disable_CSB);
reg_wizchip_spi_cbfunc(SpiDrv_ReadB, SpiDrv_WriteB);
if(TimeTask.bit.Task_10ms==TRUE)
{
tick_10msA++;
switch(tick_10msA){

```
       case 1:
            reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSA, SpiDrv_Disable_CSA);
            reg_wizchip_spi_cbfunc(SpiDrv_ReadA, SpiDrv_WriteA);
            SOCK_ESTABLISHEDA=EthernetDrv_TcpSvSockOpen(0,5000);
            ChkPhyLinkA=EthernetDrv_TcpTxByte(0,0x01);
            break;
        case 2:
           
            break;
      // }
     }
```

}

이럴때 tick_10ms switch 문이 실행이 되더라도 while 문 아래 reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSB, SpiDrv_Disable_CSB);
reg_wizchip_spi_cbfunc(SpiDrv_ReadB, SpiDrv_WriteB); 이 녀석들이 함수 콜을 계속 하다보니 case1 에 들어가도 소켓성립이 안되는것 같습니다.
그렇다면 reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSB, SpiDrv_Disable_CSB);
reg_wizchip_spi_cbfunc(SpiDrv_ReadB, SpiDrv_WriteB);

이걸 따로 만들어 줘야 할것같은데
void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void))
{
if(!cs_sel || !cs_desel)
{
WIZCHIP.CS._select = wizchip_cs_select;
WIZCHIP.CS._deselect = wizchip_cs_deselect;
}
else
{
WIZCHIP.CS._select = cs_sel;
WIZCHIP.CS._deselect = cs_desel;
}
}
void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
{
while(!(WIZCHIP.if_mode & *WIZCHIP_IO_MODE_SPI*));

if(!spi_rb || !spi_wb)
{
WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte;
WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte;
}
else
{
WIZCHIP.IF.SPI._read_byte = spi_rb;
WIZCHIP.IF.SPI._write_byte = spi_wb;
}
}

이부분을 함수이름만 바꿔서 하면 돼나요 ?

### Reply 3 by lawrence, 2018-06-25

안녕하세요

while에서 콜백함수를 계속 잡고 있으면 case 문에서 동작한다고 하더라도 제대로 동작할것 같지 않습니다.

말씀하신대로 while에서 함수호출을 하지마시고 case안에서 각각 호출하는 방법으로 변경하시면 어떨까요?

### Reply 4 by PSS, 2018-06-25

void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void))
{
if(!cs_sel || !cs_desel)
{
WIZCHIP.CS._select = wizchip_cs_select;
WIZCHIP.CS._deselect = wizchip_cs_deselect;
}
else
{
WIZCHIP.CS._select = cs_sel;
WIZCHIP.CS._deselect = cs_desel;
}
}
void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
{
while(!(WIZCHIP.if_mode & WIZCHIP_IO_MODE_SPI));

if(!spi_rb || !spi_wb)
{
WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte;
WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte;
}
else
{
WIZCHIP.IF.SPI._read_byte = spi_rb;
WIZCHIP.IF.SPI._write_byte = spi_wb;
}
}

따로 나누어줄 필요는 없는건가요 ?

### Reply 5 by PSS, 2018-06-26

안녕하세요. 계속 연락드려 죄송합니다.
소스를 첨부하였습니다.

```
		if(TimeTask.bit.Task_100ms==TRUE)
		{

         EthernetDrv_TcpSvSockOpen(0,5000);
         SendEthernetPacket_Shuttle();

            
			Task_100ms();           // 100ms 체크

		//	Load_EventCnt();        // 로그 데이터 갱신

		//	Check_SelectBtn_IN();   // OLED 입력 버튼

		//	Disp_Info(DispPage_uc); // OLED 갱신
		}

int16 EthernetDrv_TcpSvSockOpen(Uint16 sNum, Uint16 sPort)
{

    
    
    uint8_t destip[4] =     {192, 168, 0, 214};
    uint16_t destport =     5000;
    
	if(ChkPhyLink(sNum) == false)
	{
		socketclose(sNum);

		return -1;
	}

	/*
	TimerDrv_SetTimeOut(ethTimCnter, 5000);

	//while(wizphy_getphylink() == PHY_LINK_OFF)
	while(ChkPhyLink(sNum) == false)
	{
		if(TimerDrv_IsTimeOut(ethTimCnter) == true)
		{
			return -1;
		}
	}
	*/

	if(ChkTcpSockConnect(sNum) == false)
	{

		//NetConf();

		TimerDrv_SetTimeOut(ethTimCnter, 3000);

		//while(1)
		//{
			if(TimerDrv_IsTimeOut(ethTimCnter) == true)
			{
				socketclose(sNum);
#ifdef DBG_ON
				printf("%d : TCP Server Connection TimeOut (sPort %d)\r\n", sNum, sPort);
#endif

				return 0;
			}
            get_data=getSn_SR(sNum);
			switch(getSn_SR(sNum))
			{
				case SOCK_CLOSED:
                    
					if(socket(sNum, Sn_MR_TCP, destport, 0x00) != sNum)
					{
#ifdef DBG_ON
						printf("%d : TCP Server Start Fail (sPort %d)\r\n", sNum, sPort);
#endif
						return -2;
					}

					//printf("%d : TCP Server Start (sPort %d)\r\n", sNum, sPort);

					setSn_KPALVTR(sNum, 1);	// Keep Alive 5Sec

					break;
				case SOCK_INIT :
                   
					if(connect(0,destip,destport)!= SOCK_OK)//listen(sNum) != SOCK_OK) //listen client 
					{
#ifdef DBG_ON
						printf("%d : TCP Server Listen Fail (sPort %d)\r\n", sNum, sPort);
#endif
						return -3;
					}

#ifdef DBG_ON
					printf("%d : TCP Server Listen (sPort %d)\r\n", sNum, sPort);
#endif

					break;
				case SOCK_ESTABLISHED:
					if(getSn_IR(sNum) & Sn_IR_CON)
					{
						setSn_IR(sNum, Sn_IR_CON);

#ifdef DBG_ON
						uint8_t dIp[4];
						uint16_t dPort;

						getSn_DIPR(sNum, dIp);
						dPort = getSn_DPORT(sNum);


						printf("%d : Connected - %d.%d.%d.%d (dPort %d)\r\n",sNum, dIp[0], dIp[1], dIp[2], dIp[3], dPort);
#endif

						return 1;
					}
					break;
			}
		//}
	}

	return 1;
}
```

보시고 연락부탁드립니다.

### Reply 6 by PSS, 2018-06-26

wiz_NetInfo gWIZNETINFO = {
.mac = { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // Mac address
.ip = { 192, 168, 1, 210 }, // IP address
.gw = { 192, 168, 1, 1}, // Gateway
.sn = { 255, 255, 255, 0}, // Subnet mask
.dns = { 8, 8, 8, 0}, // DNS Server
.dhcp = NETINFO_STATIC
};

void InitUserEthernetDrvA(void)
{

```
InitUserSpiDrvA();

reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSA, SpiDrv_Disable_CSA);
reg_wizchip_spi_cbfunc(SpiDrv_ReadA, SpiDrv_WriteA);


uint8_t memConf[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}};

// allocate internal TX/RX Memory
if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memConf) == -1)
{
```

#ifdef DBG_ON
printf(" Ethernet : MEMORY CONFIG ERR.\r\n");
#endif
//while(1);
}

```
// Net Configuration
//NetConf();
```

}

void NetConf(void)
{
ctlnetwork(CN_SET_NETINFO, (void*) &gWIZNETINFO);

```
//DispNetInfo();
```

}

### Reply 7 by becky, 2018-06-26

안녕하세요

유선상으로 말씀드렸다시피
server와 client의 ip대역대가 맞지않아서 arp 가 정상적으로 이루어지지 않고 있는 상태입니다.
ip대역대를 맞추신후에 테스트 부탁드립니다.
또한, 통신에 문제가 있을때 ping이 잘이루어지는지 확인하시는 것이 좋습니다.
command창에서
ping 192.168.xxx.xxx
입력하시면 됩니다.

### Reply 8 by PSS, 2018-06-27

안녕하세요.
우선 소스에 time_out 설정을 하였습니다.
MCU Reset은 없어졌는데요. connect 함수 안에 while 문 안으로 들어가 timeout으로 return 됩니다. 그래서 MCU Reset은 없어졌구요 하지만 getSn_Sr 의 상태값은 0x00->0x13 반복됩니다.
w5500에서 리셋 되는것 같습니다.
제가 코딩한 부분 첨부하겠습니다.

```
wiz_NetInfo gWIZNETINFO = {
	        					.mac	= { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },	// Mac address
								.ip		= { 192, 168, 1, 210 },                     // IP address
								.gw		= { 192, 168, 1, 1},						// Gateway
								.sn		= { 255, 255, 255, 0},						// Subnet mask
								.dns	= { 8, 8, 8, 0},							// DNS Server
								.dhcp	= NETINFO_STATIC
	    				  };

wiz_NetTimeout gwiztimeout = { .time_100us = 10000};

void InitUserEthernetDrvA(void)
{


	InitUserSpiDrvA();

	reg_wizchip_cs_cbfunc(SpiDrv_Enable_CSA, SpiDrv_Disable_CSA);
	reg_wizchip_spi_cbfunc(SpiDrv_ReadA, SpiDrv_WriteA);


	uint8_t memConf[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}};

	// allocate internal TX/RX Memory
	if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memConf) == -1)
	{
#ifdef DBG_ON
		printf("  Ethernet : MEMORY CONFIG ERR.\r\n");
#endif
		//while(1);
	}

	// Net Configuration
	NetConf();
}


void main (void){
		if(TimeTask.bit.Task_100ms==TRUE)
		{

         EthernetDrv_TcpSvSockOpen(0,5000);
         SendEthernetPacket_Shuttle();

            
			Task_100ms();           // 100ms 체크

		//	Load_EventCnt();        // 로그 데이터 갱신

		//	Check_SelectBtn_IN();   // OLED 입력 버튼

		//	Disp_Info(DispPage_uc); // OLED 갱신
		}

}
int16 EthernetDrv_TcpSvSockOpen(Uint16 sNum, Uint16 sPort )
{

    
    
    uint8_t destip[4] =     {192, 168, 1, 211}; // pc ip 설정 
    //uint16_t destport =     2000;               // pc TOOL PORT 설정
    
    static uint16_t any_port =  5000;
    
	if(ChkPhyLink(sNum) == false)
	{
		socketclose(sNum);

		return -1;
	}

	/*
	TimerDrv_SetTimeOut(ethTimCnter, 5000);

	//while(wizphy_getphylink() == PHY_LINK_OFF)
	while(ChkPhyLink(sNum) == false)
	{
		if(TimerDrv_IsTimeOut(ethTimCnter) == true)
		{
			return -1;
		}
	}
	*/

	if(ChkTcpSockConnect(sNum) == false)
	{

		//NetConf();

		TimerDrv_SetTimeOut(ethTimCnter, 3000);

		//while(1)
		//{
			if(TimerDrv_IsTimeOut(ethTimCnter) == true)
			{
				socketclose(sNum);
#ifdef DBG_ON
				printf("%d : TCP Server Connection TimeOut (sPort %d)\r\n", sNum, sPort);
#endif

				return 0;
			}
            get_data=getSn_SR(sNum);
			switch(getSn_SR(sNum))
			{
				case SOCK_CLOSED:
                    socketclose(sNum);
                    
					if(socket(sNum, Sn_MR_TCP, any_port++,0x00) != sNum)
					{
#ifdef DBG_ON
						printf("%d : TCP Server Start Fail (sPort %d)\r\n", sNum, sPort);
#endif
						return -2;
					}
                    // if(any_port == 0xffff) any_port = 5000;

					//printf("%d : TCP Server Start (sPort %d)\r\n", sNum, sPort);

					setSn_KPALVTR(sNum, 1);	// Keep Alive 5Sec

					break;
				case SOCK_INIT :
                   
					if(connect(sNum,destip,sPort)!= SOCK_OK)//listen(sNum) != SOCK_OK) //listen client 
					{
#ifdef DBG_ON
						printf("%d : TCP Server Listen Fail (sPort %d)\r\n", sNum, sPort);
#endif
						return -3;
					}

#ifdef DBG_ON
					printf("%d : TCP Server Listen (sPort %d)\r\n", sNum, sPort);
#endif

					break;
               case SOCK_CLOSE_WAIT :
                   disconnect(sNum);

					break;
				case SOCK_ESTABLISHED:
					if(getSn_IR(sNum) & Sn_IR_CON)
					{
						setSn_IR(sNum, Sn_IR_CON);

#ifdef DBG_ON
						uint8_t dIp[4];
						uint16_t dPort;

						getSn_DIPR(sNum, dIp);
						dPort = getSn_DPORT(sNum);


						printf("%d : Connected - %d.%d.%d.%d (dPort %d)\r\n",sNum, dIp[0], dIp[1], dIp[2], dIp[3], dPort);
#endif

						return 1;
					}
					break;
			}
		//}
	}

	return 1;
}
```

서버로는 되는데 클라이언트는 왜 안되는걸까요?
PC IP설정은 192.168.1.211로 설정하였습니다.
허큘레스 TCP 서버로 하고 포트는 5000번 했습니다.

그리고 포럼에 이런 현상이 많은 분들이 있으신데 해결된 답변이 보이지가 않습니다.
아래는 이런 현상이 있어 포럼에 글 올린 주소 입니다,

![](https://avatars.discourse-cdn.com/v4/letter/s/7c8e57/48.png) [w5300 클라이언트 모드 동작 서버 연결시 타임아웃 오류](https://forum.wiznet.io/t/topic/1591/3) [TCP/IP 칩](https://maker.wiznet.io/c/korean-forum/tcpip-ecb9a9/131)

> 답변 감사합니다. 이리저리 해보는 중에 포트를 고정시켜놓고 테스트한것을 올렸네요 코드는 아래와 같이 새로 테스트를 해 보았습니다. [\[image\]](https://maker.wiznet.io/forum_uploads/wiznet/original/1X/7ab9a6d9d469fda1e4f4d25959068dff22b915c4.jpg) 테스트를 해본 결과 동일한 증상이었습니다. [\[image\]](https://maker.wiznet.io/forum_uploads/wiznet/original/1X/c25b5c2fa4ee3a384a72fb292261aa6d0e1b74c2.jpg) sync를 보내지만 sync ack를 받지 못하는 상황입니다. 추가로 더 확인을 해 보아야될 부분이 있을까요?

### Reply 9 by lawrence, 2018-06-27

안녕하세요 위즈네트입니다.

timeout뒤에 다시 socket을 open하는 것은 함수 flow대로 동작하는 내용입니다.

다만 timeout이 나는 이유를 확인해봐야 할 것 같습니다.

PC에서 wireshark를 실행시키신다음 TCP server를 open한뒤에 칩에서 접속을 시도하시고

wireshark에서 칩 IP로 필터링하신 결과를 보내주실 수 있으신가요?

패킷 확인뒤에 어떠한 부분에서 문제가 생겼는지 검토해 보겠습니다.

감사합니다!

### Reply 10 by PSS, 2018-06-27

[sss.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=95HZ3CiHVUdUSVYJr17n96XXkjS.zip) (13.8 KB)

패킷은 올렸는데 보드쪽에 반응이 없네요 … 0x13 0x00 이런식이로 반복되는데…
이것때문에 패킷에 나타나지 않은것 같아요

### Reply 11 by lawrence, 2018-06-27

현재 패킷을 보면 다음과 같이 chip에서는 SYN을 보내주나 PC에서 RST 패킷을 전송합니다.

chip은 RST패킷을 받으면 바로 Close됩니다.

이 경우에는 PC에서 5000번 포트가 사용중이기때문에 접속을 거절합니다.

포트 번호를 바꾸어서 접속을 시도해보세요

[![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/0/05ea483ae44a59cc9edd17e45cc8d96a2edabc0e.png) image1518×277 34.5 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/0/05ea483ae44a59cc9edd17e45cc8d96a2edabc0e.png)

### Reply 12 by PSS, 2018-06-27

[ffffffff.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=yrgoQQxU6qFdJ2uXNXe3VDtQDZd.zip) (204.8 KB)

우선 패킷 보내 드립니다.

이건 timout 하지 않았을시 MCU가 리셋됩니다.

### Reply 13 by lawrence, 2018-06-27

패킷에서 포트번호가 5000에서 6000으로 바뀌는데 의도하신 부분이신가요?

[![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/b/b21780a17672a2f8b2797005bfe7da743a2ec758.png) image1515×305 39.5 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/b/b21780a17672a2f8b2797005bfe7da743a2ec758.png)

### Reply 14 by PSS, 2018-06-27

포트 번호 바꿔서 테스트 하라고 하셔서
바꿔서 해봤습니다.
그리고 다시 서버로 바꿔서 테스트 했는데
데이터가 잘 들어 옵니다
근데 클라이언트로 하면 저런 현상이 나타나는데 다른 이유는 없나요 ?

### Reply 15 by PSS, 2018-06-28

잘됩니다 windows 방호벽떄문에 IP차단이 된겁니다. 풀었더니 되네요
감사합니다.

### Reply 16 by lawrence, 2018-06-28

정말 다행입니다. ㅠㅠ

최초에 빠르게 방화벽에 대한 부분 언급을 못해드려서 죄송합니다.

링크하나 보냅니다!

블로그인데 혹시 방화벽을 활성화할때 특정 IP를 허용하는 방법에 대한 내용입니다.

![](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/f/f30dc4905cf0c644b0b5e3ff266428535c85294d.png) [서버구축이야기!! – 24 Oct 17](http://server-talk.tistory.com/188)

![](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/c/c260d919b2147d02cafc5d709981454e79dacaf9.png)

### [Windows 방화벽 특정 포트 IP 허용](http://server-talk.tistory.com/188)

Windows 방화벽 특정 포트 IP 허용하기 이번해에는 랜섬웨어로 인한 많은 이슈가 있었으며, 랜섬웨어를 막기위해선 SMB 관련포트를 모두 차단해야된다는 결과가 발표되었습니다 그런데 SMB 관련포트를 모두 차단..

사용중에 또 막히시는 부분있으면 연락주세요.

감사합니다!

### Reply 17 by PSS, 2018-06-29

넵 덕분에 많은 도움이 되었습니다.
한가지 여줘 보고 싶은데 클라이언트 동작일때 데이터가 들어오기는 하는데 0x15 가 나타납니다.
0x13 → 0x15 → 0x17 일때 데이터가 들어오는거 아닐까요 ?

### Reply 18 by lawrence, 2018-07-02

도움이 되셨다니 다행입니다.

말씀하신대로 0x17일때 또는 CONNECT 인터럽트가 발생한 이후에 데이터전송이 가능합니다.

데이터가 수신되었다고 말씀하셨는데

패킷상으로

SYN →
← SYN+ACK
ACK->

이 과정 사이에 데이터가 들어온것인지 확인가능할까요?

감사합니다.

### Reply 19 by PSS, 2018-07-02

음 저한테는 보이지가 않습니다.
패킷 첨부하겠습니다. 확인 부탁드립니다.
그리고 온도는 답변이 나왔나요 ? [패킷.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=pRBDGDhSZ60e7AYjPO9HXSqrESX.zip) (2.0 KB)

### Reply 20 by becky, 2018-07-02

안녕하세요

패킷이 처음부터 캡쳐가 안되고 짤린것 같습니다.
보내주신 패킷상태로는 정상동작으로 보이고
소켓상태가 0x17이여야하는것이 맞습니다.

### Reply 21 by lawrence, 2018-07-02

패킷과 같이 데이터가 오가는중에도 스테이터스 값이 0x15를 유지하나요?

발열관련해서는 여쭈어봤는데 그당시 회로상으로는 특별한 이상은 발견하지 못해서

WIZ850io를 제공했었다고 하시네요

혹시 WIZ850io로 테스트 해보셨나요?

### Reply 22 by PSS, 2018-07-02

[패킷.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=xiXG9tpChc7hQQrm4OrUHX0Asqg.zip) (971.8 KB)

### Reply 23 by PSS, 2018-07-02

패킷과 같이 데이터가 오가는 중에도 0x15 로 유지 합니다.

### Reply 24 by becky, 2018-07-02

안녕하세요

ESTABLISHED상태에서는 데이터 송수신을 할 수 없게 구현되어있습니다.
상태레지스터를 읽어오는 부분 코드 보여주시면 확인해드리겠습니다.

### Reply 25 by PSS, 2018-07-02

> switch(get_state=getSn_SR(sNum))
> {
>
> ```
  		case SOCK_CLOSED:
  			if(socket(sNum, Sn_MR_TCP, sPort, 0x00) != sNum)
  			{
```
>
> #ifdef DBG_ON
> printf(“%d : TCP Server Start Fail (sPort %d)\r\n”, sNum, sPort);
> #endif
> return -2;
> }
>
> ```
  			//printf("%d : TCP Server Start (sPort %d)\r\n", sNum, sPort);

  			setSn_KPALVTR(sNum, 1);	// Keep Alive 5Sec

  			break;
  		case SOCK_INIT :
  			if(connect(0,IP_SET,sPort)!= SOCK_OK)
  			{
```
>
> #ifdef DBG_ON
> printf(“%d : TCP Server Listen Fail (sPort %d)\r\n”, sNum, sPort);
> #endif
> return -3;
> }
>
> #ifdef DBG_ON
> printf(“%d : TCP Server Listen (sPort %d)\r\n”, sNum, sPort);
> #endif
>
> ```
  			break;
  		case SOCK_ESTABLISHED:
  			if(getSn_IR(sNum) & Sn_IR_CON)
  			{
  				setSn_IR(sNum, Sn_IR_CON);
```
>
> #ifdef DBG_ON
> uint8_t dIp[4];
> uint16_t dPort;
>
> ```
  				//getSn_DIPR(sNum, dIp);
  				//dPort = getSn_DPORT(sNum);


  				printf("%d : Connected - %d.%d.%d.%d (dPort %d)\r\n",sNum, dIp[0], dIp[1], dIp[2], dIp[3], dPort);
```
>
> #endif
>
> ```
  				return 1;
  			}
  			break;
  	}
```
>
> // }
> }
>
> return 1;

입니다.

### Reply 26 by becky, 2018-07-02

패킷상에서는 W5500이 데이터를 전송하는 것으로 보이는데
코드상에서는 send하는 부분이 보이지 않습니다.
데이터 전송은 어디서 하고있는건가요??

상태레지스터가 계속 0x15라고 하신 뜻은
case문이 SOCK_ESTABLISEHED로 들어오지않는다는 말이신가요??

![](https://avatars.discourse-cdn.com/v4/letter/p/7bcc69/48.png) PSS:

> ```
  				printf("%d : Connected - %d.%d.%d.%d (dPort %d)\r\n",sNum, dIp[0], dIp[1], dIp[2], dIp[3], dPort);
```

이부분은 디버깅으로 출력되시나요?

### Reply 27 by PSS, 2018-07-02

SOCK_ESTABLISEHED 이쪽으로 들어가지가 않군요…

어떻게 이럴수가 있는건지…

그리고

```
int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
{
   CHECK_SOCKNUM();
   CHECK_SOCKMODE(Sn_MR_TCP);
   CHECK_SOCKINIT();
   //M20140501 : For avoiding fatal error on memory align mismatched
   //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
   {
      uint32_t taddr;
      taddr = ((uint32_t)addr[0] & 0x000000FF);
      taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
      taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
      taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
      if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
   }
   //
	
	if(port == 0) return SOCKERR_PORTZERO;
	setSn_DIPR(sn,addr);
	setSn_DPORT(sn,port);
	setSn_CR(sn,Sn_CR_CONNECT);
    while(getSn_CR(sn)); //67
   if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
 /*  
   while(getSn_SR(sn) != SOCK_ESTABLISHED)
   {
		if (getSn_IR(sn) & Sn_IR_TIMEOUT)
		{
			setSn_IR(sn, Sn_IR_TIMEOUT);
            return SOCKERR_TIMEOUT;
		}

		if (getSn_SR(sn) == SOCK_CLOSED)
		{
			return SOCKERR_SOCKCLOSED;
		}
	}
  */
   return SOCK_OK;
```

이 함수에 while 문 주석처리 안하면 계속 리셋 됩니다.
그래서 주석처리 했구요 ,

도대체 무엇이 문제 인지ㅜㅜ…

### Reply 28 by becky, 2018-07-02

안녕하세요

위에서도 말씀드렸지만 패킷상에서는 W5500이 데이터를 전송하고있는데 전송은 어디서 하고있는건가요??
패킷도 칩과 connection 과정 하는 부분에대한 부분이 없습니다
다시 캡쳐 부탁드립니다.

### Reply 29 by PSS, 2018-07-02

이해가 가지 않습니다만 소캣오픈 안에 있는 while 문 주석처리 한걸 다시 풀었는데 상태값이 나옵니다
위즈넷에서 라아브러리에는 while 문이 없문대요 …

어렵군요 하나 해결하면 또 나오고 ㅜㅜ

### Reply 30 by becky, 2018-07-03

안녕하세요

![](https://avatars.discourse-cdn.com/v4/letter/p/7bcc69/48.png) PSS:

> ```
  		case SOCK_ESTABLISHED:
  			if(getSn_IR(sNum) & Sn_IR_CON)
  			{
  				setSn_IR(sNum, Sn_IR_CON);
```
>
> #ifdef DBG_ON
> uint8_t dIp[4];
> uint16_t dPort;
>
> ```
  				//getSn_DIPR(sNum, dIp);
  				//dPort = getSn_DPORT(sNum);


  				printf("%d : Connected - %d.%d.%d.%d (dPort %d)\r\n",sNum, dIp[0], dIp[1], dIp[2], dIp[3], dPort);
```
>
> #endif
>
> ```
  				return 1;
```

우선 data send하는 함수를 return 1; 위로 넣는걸로 수정해주세요

### Reply 31 by PSS, 2018-07-03

[sssssss.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=uEomj00MTXZwQEXZDGQ2EXrnxm.zip) (2.2 MB)

TCP Retransmission 뜨는 이유가 timeout 이 짧아서 그런가요 ?

### Reply 32 by lawrence, 2018-07-03

안녕하세요

패킷을 확인해봤는데 여러번의 TCP 통신이 묶여있네요

혹시 문제가 되셨던 통신의 TCP Server. Client IP 주소와 네트워크 환경(TCP Server와 Client를 어떻게 구현하셨는지, 하드웨어적으로 어떻게 연결하셨는지 등)을 알 수 있을까요?

### Reply 33 by PSS, 2018-07-03

TCP server 192.168.1.150 입니다.
Client IP 192.168.1.211 입니다
네트워크 환경? TCP server는 PLC 며 중간에 허브를 통해 Client (저의 보드)를 통해 상호 통신을 합니다.
중간 허브에 PC를 연결하여 와이어샤크로 캡쳐 하였습니다.
여러번 통신이 묶여 있다는게 어떤 말씀이신지요?

### Reply 34 by irina, 2018-07-04

Sn_SR 가 0x15라는 것은 SYN 패킷을 보낸상태이고, 아직SYN+ACK를 받지 못한 상태입니다.
그렇기 때문에 ESTABLISHED상태로 들어가지 않는것입니다,

### Reply 35 by PSS, 2018-07-05

w5500 이상현상에 관련된 리스트 입니다.

1. send 함수 안에

while(1){

freesize=getSn_tx_FSR;

if( len&lt;=fressize) break;

}

fressize 값 2048 &lt;-> 2001 1~2초 반복, 후 1~2초 가 지난 후 fressize 0 가 됨 즉. len 값보다 작아 break 가 안됩니다.

1. 저의 보드에 값을 증가 지속 함, PLC GX work2 메모리에 보면 초기 증가함, 하지만 5초 정도 지나면 증가하지 않고 GX work2 또한 느려집니다.
   그리고 5초 정도 지나면 메모리에 증가 값이 확 증가하며 GX work2 도 잘 작동합니다.
   이런식으로 반복합니다.
   1_PLC로 테스트 시 패킷 정보 파일첨부
   2_PC로 테스트 시 패킷 정보 파일첨부[Desktop.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=tFz3oDghIw9SgPi3kGXQH89sGzp.zip) (458.4 KB)

2. PC(이더넷 테스트 프로그램 ) 으로 실행시키면 1, 2번 과 같은 현상은 없습니다.

3. /*
   while(getSn_SR(sn) != SOCK_ESTABLISHED)
   {
   if (getSn_IR(sn) & Sn_IR_TIMEOUT)
   {
   setSn_IR(sn, Sn_IR_TIMEOUT);
   return SOCKERR_TIMEOUT;
   }
   ```
  if (getSn_SR(sn) == SOCK_CLOSED)
  {
      return SOCKERR_SOCKCLOSED;
  }
```
   }
   */

이 부분을 주석처리 안하면 와치독 발생
주석처리 시 와치독 없음
제가 timeout 을 4000, retry_cnt 1 설정 하였습니다.
하지만 계속 와치독 발생 입니다.
이상합니다.

### Reply 36 by lawrence, 2018-07-05

안녕하세요 답변이 늦었습니다.

1. freesize는 sock이 전송할 수 있는 버퍼가 남아있냐는 것을 의미합니다. freesize가 0인 것은 이전 send data가 아직 전송되지 않거나 버퍼가 꽉 차있다는 의미입니다.
   그리고 아래의 코드가 저희가 제공하는 라이브러리의 코드입니다.
   보시면 while안에서 확인하지 않고 break로 나오지 않습니다.
   코드가 저희가 제공하는 라이브러리와 맞는지 다시한번 확인해주세요

![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/0/02083fe056869fbd2a321bb53f6c3a3ea4773619.png)

1. PLC 패킷을 확인해봤습니다만 의문이 드는게 있습니다.
   PC패킷의 경우 210에서 150으로 47byte의 데이터를 지속적으로 전송합니다.
   그러나 PLC의 경우 그렇지 않습니다.
   아래 그림에 보시면 150의 ACK가 지속적으로 증가합니다. 그뜻은 210에서 94byte를 지속적으로 전송합니다.
   [![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/d/d9911189aec8fce1ef55e518bf213438b4514237.png) image1489×581 61 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/d/d9911189aec8fce1ef55e518bf213438b4514237.png)

   그리고 여기서 부터는 150이 11byte의 데이터를 지속적으로 전송하면서 이제는 210으로 부터 47byte의 데이터를 받기 시작합니다.
   [![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/4/447f04b0d8921fa36511a5421f7cbdf9fd35a156.png) image1297×554 62.6 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/4/447f04b0d8921fa36511a5421f7cbdf9fd35a156.png)

그리고 이때부터는 다시 150이 데이터를 받기만 합니다.

[![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/7/7ba74863337176c45c0c553859839ec7ac1c85f7.png) image1254×540 15 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/7/7ba74863337176c45c0c553859839ec7ac1c85f7.png)

마지막으로 수신만 하던 150은 버퍼 사이즈가 없어서 알림메시지만 지속적으로 보냅니다.

[![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/f/ffdaa619744a020425c7adf5b9b4883745c791bd.png) image1447×552 63 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/f/ffdaa619744a020425c7adf5b9b4883745c791bd.png)

결과적으로 PC패킷과 PLC패킷의 동작은 전혀 다른 동작을 수행하고 있습니다.
이부분에 대한 정확한 설명이 필요해보입니다.

1. 2번과 동일하게 현재 PC와 PLC와는 서로 다른 동작을 하고 있는 듯 보입니다.

2. retry_cnt를 증가시켜주세요 1은 재전송이 한번이라도 발생하면 바로 TIMEOUT이 발생합니다.

감사합니다

### Reply 37 by PSS, 2018-07-05

답변 주셔서 감사합니다.

1. while(1)
   {
   freesize = getSn_TX_FSR(sn);
   tmp = getSn_SR(sn);
   if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
   {
   socketclose(sn);
   return SOCKERR_SOCKSTATUS;
   }
   if( (sock_io_mode & (1&lt;&lt;sn)) && (len > freesize) ) return SOCK_BUSY;
   **if(len &lt;= freesize) break;** 이부분 에 있습니다.
   }

2. PC와 PLC 서로 다른 동작을 하고 있는건 알고 있습니다.
   PC와 w5500 바로 연결 하였으며 테스트 프로그램은 SerialPortMon 이라는 프로그램을 사용하고 있습니다.
   PLC 는 허브로 연결, w5500 또한 허브로 연결 , PC 또한 허브로 연결 하였습니다. 그리고 와어샤크로 패킷정보
   를 보았습니다.

### Reply 38 by lawrence, 2018-07-05

[github.com](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c)

#### [Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c)

```
//*****************************************************************************
//
//! \file socket.c
//! \brief SOCKET APIs Implements file.
//! \details SOCKET APIs like as Berkeley Socket APIs. 
//! \version 1.0.3
//! \date 2013/10/21
//! \par  Revision history
//!       <2015/02/05> Notice
//!        The version history is not updated after this point.
//!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
//!        >> https://github.com/Wiznet/ioLibrary_Driver
//!       <2014/05/01> V1.0.3. Refer to M20140501
//!         1. Implicit type casting -> Explicit type casting.
//!         2. replace 0x01 with PACK_REMAINED in recvfrom()
//!         3. Validation a destination ip in connect() & sendto(): 
//!            It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
//!            Copy 4 byte addr value into temporary uint32 variable and then compares it.
//!       <2013/12/20> V1.0.2 Refer to M20131220
//!                    Remove Warning.
```

This file has been truncated. [show original](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c)

여기 참조하시면 됩니다.

참고로 위의 라이브러리라 공식적인 최종 라이브러리입니다.

혹시 함수의 지속적인 오류가 있으시면 위의 라이브러리로 교체하시는걸 추천드립니다

감사합니다

### Reply 39 by lawrence, 2018-07-05

해당 내용은 위의 코드에서 send() 함수를 참조하시면 됩니다.

### Reply 40 by PSS, 2018-07-05

[PLC.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=8otgxrNlEbhHeyRRXDqR5t4nCBx.zip) (65.4 KB)
우선 패킷 보냈습니다.

그리고 while(1)
{
freesize = getSn_TX_FSR(sn);
tmp = getSn_SR(sn);
if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
{
socketclose(sn);
return SOCKERR_SOCKSTATUS;
}
if( (sock_io_mode & (1&lt;&lt;sn)) && (len > freesize) ) return SOCK_BUSY;
if(len &lt;= freesize) break; 이부분 에 있습니다.
}

이부분 freesize 부분이 감소 합니다.

그리고 와치독이 걸립니다.

### Reply 41 by lawrence, 2018-07-05

와치독이 걸린다면 펌웨어가 돌다가 send()에서 뻗었다고 생각해도 무방하나요?

while문전에

freesize = getSn_TxMAX(sn);
if (len > freesize) len = freesize; // check size not to exceed MAX size.

이 내용에 대한 코드가 존재하나요?

일단 while에서 빠져나오지 못하는 이유는 없습니다.

freesize 값은 while동안 변할 수없는 값입니다.

만약 문제가 있으시면 일단 while문을 전부 주석처리하셔서 동작시켜보세요

### Reply 42 by PSS, 2018-07-05

[PLC1.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=6fz875usHqB6h3HIpLXclxxFnjM.zip) (139.2 KB)

### Reply 43 by lawrence, 2018-07-05

재접속 하는 부분이 아래의 부분입니다.

210에서 SYN패킷을 보냈을꺼고 150에서 그에 대한 SYN + ACK을 전송하는 부분입니다.

[![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/8/8bad7a8c8115ea76794c227cd23781da675d57f8.png) image1570×644 74.1 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/8/8bad7a8c8115ea76794c227cd23781da675d57f8.png)

### Reply 44 by PSS, 2018-07-06

안녕하세요.

우선 데이터가 끊어 지는 부분은 약간의 수정으로 처리 하였습니다.
그냥… plc에서 들어오는 데이터 11byte이라 getSn_RX_RSR(0); 이용하여 0byte 일 경우 소켓 클로즈 처리 할려고 했는데 getSn_RX_RSR(0); 이 값을 보니 , 0~ 2048 증가 하는것 같더라고요 … 제 생각에 11byte라고 떠야 하는데 그게 아니고 또한 2048이 넘으면 pLC가 멈추는 현상이 있는것 같았습니다. 그래서 2048 넘어가면 소켓 클로즈 처리 했습니다. 결국 이런 방법을 이용하여 데이터는 계속 받고 있습니다. 다만 걱정되는 부분은 데이터를 받다가 소켓 클로즈 되면 몇 바이트를 PLC에 못 보낼수 있다고 생각됩니다.
혹시 이런 방법 말고 다른 방법은 없을까요 ?

이제 거의 다 된 느낌이네요 ~…

덕분에 공부도 되고 감사했습니다.

### Reply 45 by lawrence, 2018-07-09

안녕하세요

RX_RSR은 Socket이 Recv한 데이터 크기를 나타냅니다. Socket Recv Buffer가 2K byte라면 RX_RSR값은 2048이 최대값이 맞습니다. 따라서 RX_RSR이 2048인 경우 Socket은 더이상 Recv할 Buffer가 없기때문에 PLC와 TCP 통신중이라면 PLC쪽에서 데이터를 전송할 수 없습니다.
RX_RSR은 사용자가 Read하지 않는한 값은 계속 누적됩니다. (Recv를 통해 데이터가 Buffer에 쌓이므로)
따라서 RX_RSR이 0보다 큰경우는 무조건 사용자측에서 Buffer의 데이터를 읽어가는것이 통신지연이나 데이터 로스를 막을 수 있습니다. (Read하지 않으면 RX_RSR은 2048이 되고 데이터를 더이상 수신할 수 없습니다.)

만약에 2048이 너무 적다고 생각되시면 Socket Recv Buffer Size(Sn_RXBUF_SIZE)를 증가시키는 것도 방법입니다.
그러나 가장 중요한 것은 RX_RSR이 0보다 큰 경우에는 Read를 해주셔서 Buffer가 가득차지 않도록 해주시는것이 통신과정에서 중요해보입니다.

감사합니다.

### Reply 46 by PSS, 2018-07-09

넵 답변주셔서 감사합니다.

말씀하신대로 저도 그 부분에 대해서 생각을 했습니다.

그래서 오늘 테스트 해보니 잘되네요…

그냥 send 만 하면 될듯 했는데 그게 아니였네요 …

recive 버퍼에 자동으로 클리어 해주는 줄 알았습니다.

지금은 온도가 50도 정도 되는데 온도만 커버 된다면 무리 없을듯 합니다.

감사합니다.

### Reply 47 by lawrence, 2018-07-09

잘되신다니 고생하신 보람이 있으셔서 다행입니다!

온도부분은 가격적인 측면을 잘 몰라서 좋은 조언일지는 모르지만

회로자체적으로 해결이 힘드시다면(모듈로도 대체하기 어려우시다면)

방열판 부착이 도움이 되실겁니다

감사합니다

### Reply 48 by PSS, 2018-07-09

덕분에 많은 도움이 되었습니다.
협조해주셔서 감사합니다.

우선 계속 에이징테스트 해봐야겠네요 .

---

Source: https://maker.wiznet.io/forum/12961
