View previous topic :: View next topic |
Author |
Message |
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
TCP server |
Posted: Thu Feb 03, 2011 9:27 am |
|
|
Hi All,
I want to transfer data between a PC and a PIC tcp server, I am using PIC18F67J60. The transfer rate will be not more than 5 bytes/sec.
I tried ex_13b which worked well but only in my LAN. It hangs after some time when I test it through the internet. I did some tests with the suplied TCP client.exe and with hyperterminal winsock.
I use this for sending data to the PC:
Code: |
void send(int data){
if(TCPIsPutReady(c_socket)) {
TCPPut(c_socket,data); //socket,data
TCPFlush(c_socket);
}
}
|
and for receiving:
Code: |
void receive(){
int data;
if(TCPIsGetReady(c_socket)) {
while (TCPGet(c_socket, &data)) printf("\n\rdata=%u",data);
}
}
|
Is there any other method that I can use? any other example or any ideas why there is a problem over the internet and not locally?
Thanks in advance! |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Thu Feb 03, 2011 3:11 pm |
|
|
I have not played with that code, but a couple of things to keep in mind.
- Many ISP's will block the ftp (and other) ports to their users (you can ftp out, but they don't want you setting up ftp servers on their network).
- Another potential pothole in the road (based on experience ) is that when you close a port, you tell the operating system you are done with it. The OS may not get around to actually closing the port for some period of time and as such, if you try to open that port again very soon after closing it, you get errors about the port being in use (took me a while to track that one down and understand the problem).
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Fri Feb 04, 2011 9:50 pm |
|
|
I haven't done this sort of long-lived connection, but have you tried calling TCPIsConnected() and re-connecting if it isn't? If your comms is 'bursty' a computer somewhere may be dropping an apparently idle connection.
Alternatively, have you considered UDP packets? You need to be aware that they aren't reliable and may be dropped, but they're typically pretty good and you can always implement simple flow control of your own. _________________ Andrew |
|
|
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
|
Posted: Tue Feb 08, 2011 8:26 am |
|
|
Thanks for the reply guys.
The problem is that the connection holds for ever when used in my local area network. why should there be a difference through the internet? |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Tue Feb 08, 2011 9:39 am |
|
|
Your local LAN will be far more reliable and far faster than the Internet. Just because you've been lucky up to now on your LAN doesn't mean you'll stay lucky tomorrow... _________________ Andrew |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Tue Feb 08, 2011 9:46 am |
|
|
I doubt very much that an ISP will block FTP but anyway.
With the internet (no idea what your connection is) there is more chance for a delay/error/disconnection.
If you have allowed the PIC only 1 socket, the PC will connect to this and transmit/recieve data. When there is a disruption the PC will retry and then close the socket and try to open a new one. The PIC with it's 1 socket, still open will wait either indefinately or until it times out (I assume it is timing out for you).
This is where the delay comes from.
Now you can configure the PIC for more than 1 socket, but if you are using the code supplied from CCS (which I have been), there are bugs in it, especially for multiple sockets. I have managed to fix most for my app, It did turn out that I was using an older version of the CCS (microchip converted) code but I don't think they have fixed it.
You could reduce the timeout making sure it is long enough for your interval.
Or it could be something else. |
|
|
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
|
Posted: Thu Feb 10, 2011 12:13 am |
|
|
I have allowed 5 sockets for the PIC connections. The client software hangs but the PIC thinks it is still connected. There is no error there. Maybe TCP was no meant to be used for this purpose. Are there any suggestions-examples for my case?
I do not want to use UDP because I do not want to drop any bytes in the way. I need to transfer 5 byte packets to the PIC and back with 200mS delay between each byte. It is a very low rate and I thought it would be very easy. Should I try UDP just to see if it hangs or not?
Keep in mind that for client software I used:
a) the suplied TCP client.exe
b) My VB application using winsock
c) hyper terminal using winsock.
In all cases the comunication stops after some time when used through the internet.
Thanks |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Thu Feb 10, 2011 6:17 am |
|
|
I think UDP would work well, even though you're going to have to implement buffering, sequencing and acknowledgements. UDP can be made reliable! _________________ Andrew |
|
|
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
|
Posted: Thu Feb 10, 2011 8:49 am |
|
|
First results with ex12.c UDP example:
"Could not bind socket. Address and port are already in use." |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Thu Feb 10, 2011 11:38 pm |
|
|
MAX_UDP_SOCKETS must be defined for the number of UDP ports you're using. Also, you can't use the same socket that you might already be using for TCP.
eg here's cut-down NTP code from one of my projects: Code: | NODE_INFO ntp_info;
UDP_SOCKET ntp_socket;
// setup socket for receiving
void ntp_init(void)
{
ntp_socket = UDPOpen(Config.udpPort + 1, NULL, INVALID_UDP_SOCKET);
}
void ntp_sendreq(void)
{
UDP_SOCKET s;
// ntp_info.IPAddr set elsewhere
s = UDPOpen(Config.udpPort + 1, &ntp_info, NTP_PORT);
if (s != INVALID_UDP_SOCKET)
{
UDPPut(0); // however many
UDPFlush();
UDPClose(s);
}
}
void ntp_task(void)
{
if (ntp_socket == INVALID_UDP_SOCKET) { return; }
if (UDPIsGetReady(ntp_socket))
{
int8 data;
UDPGet(&data); // however many
UDPDiscard();
}
} | Note "port+1" is because "port+0" is for my main data I/O, so "port+1" was handy. It's just an arbitrary port >1024. _________________ Andrew |
|
|
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
|
Posted: Fri Feb 11, 2011 4:00 am |
|
|
Andrew,
I am afraid I cannot follow your example because my experience on this field is limited. For now I will have to stick with the CCS udp example until I understand how it works but unfortunatelly the CCS UDP example does not work! It does not connect with the UDP.exe and I do not get any error messages. Just that the PIC is listening...
It would be great if you could provide a working example to start with.
Thanks |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Fri Feb 11, 2011 9:04 am |
|
|
OK, break it down into steps. Transmitting first. Call this function on the PIC, say once a second (sorry, I also missed clearing the MAC above): Code: | void test_send_udp(void)
{
UDP_SOCKET s;
NODE_INFO udp_info;
// target IP address here:
udp_info.IPAddr.v[0] = 192;
udp_info.IPAddr.v[1] = 168;
udp_info.IPAddr.v[2] = 1;
udp_info.IPAddr.v[3] = 10;
// clear MAC
udp_info.MACAddr.v[0] = 0xFF;
udp_info.MACAddr.v[1] = 0xFF;
udp_info.MACAddr.v[2] = 0xFF;
udp_info.MACAddr.v[3] = 0xFF;
udp_info.MACAddr.v[4] = 0xFF;
udp_info.MACAddr.v[5] = 0xFF;
s = UDPOpen(12345, &udp_info, 23456);
if (s != INVALID_UDP_SOCKET)
{
// put some data in the packet that you'll recognise
UDPPut(0);
UDPPut(1);
UDPPut(2);
UDPFlush();
UDPClose(s);
}
} | That will send a UDP packet with 3 bytes (0, 1, 2) to 192.168.1.10:23456 from port 12345 on your PIC. Adjust those settings for your purpose.
Use a program on your PC called Wireshark (Google it). You can set it to display all UDP packets sent to port 23456, for example. It's invaluable for troubleshooting network comms. _________________ Andrew |
|
|
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
|
Posted: Fri Feb 11, 2011 2:00 pm |
|
|
I tested this with wireshark, it sends the 3 bytes correctly.
I think that the problem is in the UDP.exe.
I did not know that you can set the receiver's IP in UDP transfer.
The PIC should be act as a server, meaning that it does not know who (which IP) will connect and receive the data.
Now how can I receive these bytes from the PC side?
Thanks!! |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Fri Feb 11, 2011 9:11 pm |
|
|
georpo wrote: | I tested this with wireshark, it sends the 3 bytes correctly.
I think that the problem is in the UDP.exe.
I did not know that you can set the receiver's IP in UDP transfer.
The PIC should be act as a server, meaning that it does not know who (which IP) will connect and receive the data. |
In that case, referring to my post on Fri, ntp_init() sets up a port for receiving packets. Then ntp_task() is called from an idle loop to handle received packets.
To reply, after UDPDiscard(), I call UDPPut+UDPFlush. UDPClose is not called, leaving the socket open to receive another packet. The reply automatically goes back to the IP:Port the received packet came from.
Quote: | Now how can I receive these bytes from the PC side? |
That's entirely up to your PC development end, but there should be plenty of PC-based UDP examples to find, no matter what language you're using. _________________ Andrew |
|
|
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
|
Posted: Sat Feb 12, 2011 2:33 am |
|
|
and something strange...
I use wireshark but I see UDP traffic only if I use ports 1024 and 1025.
I tried other port numbers but no luck.
The PIC seems to send the packets (the magjack led flashes) but I do not see them in wireshark. |
|
|
|