µTasker Forum > µTasker general

Using TCP in the uTasker project

<< < (3/10) > >>

mark:
Hi Neil

Take a look at the first example. It uses:

if (fnSendTCP(Socket, (unsigned char *)&test_message->tTCP_Header, 4, TCP_FLAG_PUSH) > 0)

when sending.

Note that the buffer should also supply space for the TCP layer to add its header. This is so that TCP doesnt have to copy data contents to merge it with its header and is a rather specific solution - however once you have the buffer set up accordingly it should be easy to use.

Your copy is effectively giving  a pointer to your test message which TCP will overwrite with the header and it will then send 5 extra bytes beyond the header length, which will be a bit random since this is beyond the end of your buffer.

If you use a structure as in the example and build your test message up in the data part of the buffer it should then send the content that you are expecting.

Good luck

Regards

Mark

neil:
Hi Mark,
  Thanks for the reply.
It worked fine as you mentioned, I just never realised that the header had to be included, just thought need to provide a buffer,but worked fine.

It strange, as I tried it , and all worked fine, I then closed my server and simulator. Then re-ran them the same way. The simulator tried to connect, but a connections didnt make a connection. Ive tried it several times, but no luck. Ive managed 2 connections from about 10 attempts. If I run my windows client application we use, we can do the exactly the same thing I am trying with the simulator, and everytime it connects tot he server.

Regards
Neil

neil:
Hi mark,
  Regarding the previous problem of not being able to connect.

With the problem above, not connecting, I was trying it on the sumilator. I now copied the code into the 52233 flash. And it worked fine, without modifying any code.

Within the call back routine above 'static int fnTestListener(USOCKET Socket, unsigned char ucEvent, unsigned char *ucIp_Data, unsigned short usPortLen)' is 'ucIp_Data' a pointer to the data read in, and 'usPortLen', The number of characters?

Regards
Neil

mark:
Neil

I cant explain why it is not working every time with the simulator. If you send me an Ethereal recording I may be able to see what is happening.

ucIp_Data is a pointer to either the data in the input buffer or the IP address of the connection partner (in the same format as all local IP addresses). usPortLen is either a port number or a length, according to the event type.

Here is a complete list:

TCP_EVENT_ARP_RESOLUTION_FAILED. ucIp_Data is a pointer to the remote IP address. usPortLen is the port number.
TCP_EVENT_CONREQ. ucIp_Data is a pointer to the remote IP address. usPortLen is the port number.
TCP_EVENT_CONNECTED. ucIp_Data is a pointer to the remote IP address. usPortLen is the port number.
TCP_EVENT_ACK. ucIp_Data is a pointer to the remote IP address. usPortLen is the port number.
TCP_EVENT_CLOSE. ucIp_Data is a pointer to the remote IP address. usPortLen is the port number.
TCP_EVENT_ABORT. ucIp_Data is a pointer to the remote IP address. usPortLen is the port number.
TCP_EVENT_CLOSED. ucIp_Data is a pointer to the remote IP address. usPortLen is the port number. Exception: if REUSE_TIME_WAIT_SOCKETS option is enabled it is possible that a connection in the TCP_STATE_FIN_WAIT_2 state will be prematurely terminated rather than rejecting a connection due to no sockets available in the TCP socket pool. In this case the port number is 0.

TCP_EVENT_REGENERATE. ucIp_Data is not used and is 0. usPortLen is a length - how many bytes need regenerating.

TCP_EVENT_PARTIAL_ACK. ucIp_Data is a pointer to the remote IP address. usPortLen is a length - the number of bytes not yet acked.

TCP_EVENT_DATA. ucIp_Data is a pointer to the received data content. usPortLen is a length - the number of bytes of data.

Regards

Mark

mark:
Here is a simple TCP client example:

Earlier I gave a simple example of creating a TCP server socket which could be connected to from a remote client. In that case it was necessary to set the socket to listening state so that it could respond to connection attempts.

In the case of the client it is not necessary to set the socket to any special state, however it is also possible to set the socket to listening state but subsequently use it to connect as a client to a remote server. This means that any socket can be used as a client socket - but it can only establish a client connection if it has not already a connection from a remote client. (Put another way, a socket can only handle one connection; either the connection is established as a server from the listening state or as a client from any state).

The following code wil thus create a socket for client use and then attempt to establish a connection to a remote server.

USOCKET test_client_socket = fnGetTCP_Socket(TOS_MINIMISE_DELAY, TCP_DEFAULT_TIMEOUT, fnTestListener);

As in the case of the server, there must be a free socket available and the user must ensure that there are enough sockets for a particular application in the socket pool. USER_TCP_SOCKETS defines the number of sockets reserved for use by the application.

If no socket is available for use, the routine fnGetTCP_Socket() will return a negative error code.

static unsigned char ucRemoteIP[IPV4_LENGTH] = {192,168,0,101};
#define TEST_TCP_PORT 0x1234
if (test_client_socket >= 0) {
    fnTCP_Connect(test_client_socket, ucRemoteIP, TEST_TCP_PORT, 0, 0);
}

This call only attempts to establish a connection when the socket is valid. It causes TCP to send a connection request (SYN) to the IP address 192.168.0.101 on port 0x1234. Note that all IP addresses in the uTasker project are defined as arrays and not as strings which is another common method ("192.168.0.101" is therefore not a valid IP address definition).
In the example, the last 2 parameters of the fnTCP_Connect() call are 0. The first can be used to define the local port number but typically a client uses a more or less random port number when connecting and so a 0 informs TCP that it should define the port using its standard algorithm. The last parameter allows a maximum TCP window size to be specified. This will not be discussed further here since it will be used in a later topic. A zero informs TCP to use the standard rx window size, which is equivalent to the maximum TCP payload of an Ethernet frame (1460 bytes).


The client connection attempt may cause the connection frame to be sent out onto a local LAN (if the IP address belongs to the local subnet) or else to the default gateway address if it is outside of the local subnet. In either case, if the destination IP address does not yet exist in the ARP table this will first be resolved by the ARP protocol.

The way that ARP operates is transparent to the user when connecting. Either the connection is sent (either immediately or after ARP has resolved the IP address) or it can not be sent due to the fact that ARP - after several attempts, and a delay of about 5s - still can not resolve. The the callback is un this case called with event TCP_EVENT_ARP_RESOLUTION_FAILED.

Assuming that the connection is successful, TCP will call the listener with the event TCP_EVENT_CONNECTED.

Once connected, the rules for the connection are the same. Whether client-server or server-client the connection is effectively peer-peer.
As with the listener case, either party can close the TCP connection.


Note that the Time Server demo in the uTasker demo project shows how a client connects to a remote server, which automatically sends back the time before immediately closing the TCP connection. To activate this, set the define USE_TIME_SERVER in config.h.




Regards

Mark

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version