TCP Client problem

Hi,
I do ethernet on stm32 microcontroller and i am using W5200 ethernet shield. I have already done tcp server and everything it’s OK. My board is a server, my computer is a client. I can send data to computer and in terminal i receive it. How i said everything works.
But now i want to do tcp client on my board and computer will be server. I have problems. I use W5200 library. In application note i read that there is one difference between tcp_loopback client and server. In sock_init i have to change listen(s) function to connect function and i did it, but it doesn’t work. Of course i have written also destination ip, port and now i’m wondering to write also destination mac adress. Please help me. Where can be a problem since tcp server works?

Hi.

What kind using complie & IDE tool?

And what using example code?

I think… code problem…

Please tell me the example code.

Thank you

Edward, I send example code to your email. I’m using crossstudio for ARM 3.5.

Hi.

where are downloaded from this exmaple code?

And I need main code.

Thank you

Ok, here is a program in C++.
Thank you for your attention.

I have one more question. Is it possible to simultaneously operate two sockets: one like a server, the second like a client?

Yes.

You need to ensure you write correct gateway address. When you issue connect request command for W5200, it sends ARP request to gateway. If gateway is not functional process terminates.
In general you should have the following fields properly preset for client mode:

  • own IP address;
  • subnet mask;
  • gateway address;
  • destination and source ports.
    Your settings

char mac[6]={0x00,0x16,0x59,0x00,0x00,0x00}; ethPort = 5555; char ip_addr[4]; char subnet_mask[4]; char gateway[4]; gateway[0] = 10; gateway[1] = 10; gateway[2] = 254; gateway[3] = 254; subnet_mask[0] = 255; subnet_mask[1] = 255; subnet_mask[2] = 0; subnet_mask[3] = 0; ip_addr[0] = 10; ip_addr[1] = 10; ip_addr[2] = 20; ip_addr[3] = 5;
and

uint8 _ipp[4] = {10,10,20,30}; unsigned int _port = 5555;
seem to be fine as far as I understand it, you connect ports 5555 at both ends, the only question is if 10.10.254.254 is functional as gateway.
What debug output says?

Eugeny! Thank you for all your support. It was hardware problem. Now it’s works. But i have one more question. I can send data, but when terminal wasn’t open program don’t go in connect function to this function:

if (getSn_IR(s) & Sn_IR_TIMEOUT) { IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT)); // clear TIMEOUT Interrupt ret = 0; break; }
only goes on. But it’s works.
And secondly, when i open terminal for the first time client always connect to server in any time. Then I disable the terminal, and when i want to open the terminal within a few seconds, client always connects to the server. But when i wait not few seconds, but few minutes it does’t want to connect to the server. Any ideas where is a problem?

If you try to connect to device without it waiting for connection on specific port you will not connect anywhere and the device you are trying to connect from will timeout: getSn_IR(s) & Sn_IR_TIMEOUT will become true (timeout bit will be set to 1 in socket’s interrupt register).
Not sure I understand the second question.

I will try explain my problem one more time. In function connect after function

while ( IINCHIP_READ(Sn_SR(s)) != SOCK_SYNSENT )

when i turn on in terminal LISTEN i schould go to this function

if(IINCHIP_READ(Sn_SR(s)) == SOCK_ESTABLISHED) 

or when I don’t listen a port, after few timeouts I schould go to this function

if (getSn_IR(s) & Sn_IR_TIMEOUT)

But my problem is that the program don’t go to neither function. But when I listen the port, I link to the server, because in terminal I could receive the data. Summing up it works, because in terminal I have connection, in eth_loop_tcpc - program after reading register (getSn_SR(s)) go to case: SOCK_ESTABLISHED, but and it is the problem in function connect() program don’t go to this function -

if(IINCHIP_READ(Sn_SR(s)) == SOCK_ESTABLISHED)

in spite of the program works.

I am sorry I hardly understand what you ask.

Regardless of your socket listening or actively connecting, after successful connection process, status register gets value of 0x17 (“established”). This is persistent state which will be there until any of connection participants decide to disconnect or there will be hardware failure on the line.

Timeout occurs when W5200 did not get any response from remote device for its network request. Timeout will NOT occur if remote devices respond to W5200 (whatever response it will be).

Synsent 0x15 is a transient state leading to either established state 0x17 through synreceive 0x16, or to disconnection 0x00. W5200 will go through this state when you instruct it to connect, or if there’s incoming connection for listening socket.

The most important for you is that you can send and receive information only in “established” 0x17 state (for TCP sockets). All other transient states of W5200 are important for troubleshooting purposes when something goes wrong and you do not reach 0x17.

Sorry! I will try one more time.
My problem: I send software to the flash of micro. When I listen destination port for the first time, micro (client) link to the computer(server) and everything is ok, I can send data. But now when i close the connection and I try link to the server after a few minutes, I can’t do that. Micro don’t link to the computer, because program freezes (I debug it). And I think something wrong is in connect function. I put there breakpoints and i see that program goes to loop

while ( IINCHIP_READ(Sn_SR(s)) != SOCK_SYNSENT )

and he out of the loop before timeout occur or sock_established, so the variable ret is always =1, because has been previously set. So why is it?

Server is some computer, not W5200-based.
Client is device based on W5200 chip.
First time connection from client to server works, second time it hangs in synsent state.
Correct?

First of all, if client (W5200 device) disconnects from server (and NOT server disconnects client) you should instruct W5200 device to explicitly perform DISCON command on the socket before closing it. Second, when you connect second time, you should use different source port for the socket.

Yes Yes, correct. I am happy you understand.
What if server disconnects client?
Thank you for your patience.

If server disconnects client then W5200 does not need (and should not) use DISCON command because disconnection was already processed by the server. W5200 just closes socket, then reopens it with another source port number and tries to connect again.

I changed source port in socket when i connect for the second time, i perform disconnect function (discon command) and then close socket. Unfortunately it did not help. I have the same problem. First time connection from client to server works, second time it hangs in synsent state. If i want to connect for the second time, i have to restart my micro.

I do not have simple answer for it. What I would do:

  1. when connecting first (when connected) AND second (being stuck with synsent state) times, make a dump of main registers and socket registers. Then see if they are all valid, and compare them. Probably there’s some problem in W5200 setup when you restart socket second time;
  2. using Wireshark on the server and capture communication between W5200 board and server. First time it will work. second time you need to see if SYN packet is really received by the server’s interface and see what server does after this packet. I would also compare two SYN packets - sent first time and sent second time;
  3. What is your server? Operating system? Server software?
  1. When i don’t listen the port it of course no connect, but Sn_SR register is always 0x15 (synset) (i see it in connect function before return order). When i listen the port (for the fist time) in connect function in the same place Sn_SR register is also 0x15, but in tcp_loop it has 0x17 and perform case: SOCK_ESTABLISHED (in terminal i see the connection and i can send data)
  2. I used Wireshark. I send you foto in attachment. But i saw that it hangs after first close no at the time when i want to connect for the second time, but earlier. In Wireshark after first close, I capture communication between W5200 board and server, and at some moment communication between client and server ends/hangs, because i can’t see new SYN packets. So i can’t compare first and second connection attempt, because there is no new packet when i push the button to second connect.
  3. I don’t no at all, but i think operating system. In pc i use hercules terminal.



Looking to the shot you provided there’s clearly a problem, and I think you are right that it happens after you close connection for the first time.
I can not match what I see with your previous setup (it was 10.10.20.5 for W5200 and 10.10.20.30 for remote deice, both ports 5555).
I assume here 9.72 (560xx) is W5200 and 9.106 (9001) is remote network device.

I bet that your code at W5200 side is continuously writing garbage or unexpected values into socket’s command register, causing W5200 continuously sending SYN packets and server of course responding with RST packet. These commands could be: CONNECT and DISCON. Probably others can make same effect. Your task now is to monitor all writes to socket’s CR, when these writes occur and what is being written there.

Note that when you issue 0x04 (CONNECT) command you should wait until connection is established or timeout occurs. You should not send another connection request until W5200 finishes executing connect command - by ensuring that command is accepted (command register becomes 0x00) and connection request is complete (status went to 0x17 ESTABLISHED or to 0x00 CLOSED) [you can use IR register to monitor the connection progress - up to you].

And in general, if connect fails, socket goes to CLOSE state (0x00), OR after you issue DISCON or CLOSE command (finishing previous session), you will have to reopen the socket using 0x01 OPEN command.

Please check your code for both issues: garbage write to CR and wrong socket workflow.

Everything is OK. I think it’s works. What was wrong? When you wrote " You should not send another connection request " I realise that connect function is in main loop, so it perform for every tick time clock. So I changed my code and now it send SYN packets not every time, but once in three seconds, therefore W5200 manage to finish executing connect command on time.
Thank you for your help.
PS Yes i have to changed both IP, sorry that i didn’t tell you about this.