TCP Server using InterNiche miniSockets

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

TCP Server using InterNiche miniSockets

4,298 次查看
ColdFireHot
Contributor I
Hi all,
 
I am having a blast with my M52233DEMO board.  Just a little trouble understanding InterNiche.
 
I have been able to get a socket listening on port 10001 and accepting connections.
I then just echo the data back by using send().
The problem is that the listening socket is still actively listening on the same port thereby allowing another connection to be made.
This just adds another socket to my msring but this is a problem when sending data back as it over writes the local socket descriptor that I made from the first call to msring_del().
 
Being new to TCP/IP programming, I'm looking for any assistance in how to handle blocking a second connection, keeping it from being successful while the first connection is active.  How do I get the underlying tcp code to send a [RST, ACK] to any subsequent requests.
 
See attached code.
 
Thanks,
Mark
 
标签 (1)
0 项奖励
8 回复数

1,105 次查看
wyliek
Contributor I
Hi Mark

I probably wont be able to help you but I have a few questions.

I am trying to implement the same application as you are (get the demo board to simply echo back received packets). I have tried your code but have not yet got it to work. Since you have obviously been working with this here goes with the questions.

1. What software are you using to send TCP packets to the demo board? I have written my own simple program, but I want to rule out the possibility of it being the source of any problems by using something more reliable. Any suggestions?

2. Is it necessary to use a msring structure if I only want to work with one connection (socket)?

3. It seems that with this code:

for (j = 0; j
m_send(My_so, (char *)buffer, length);

you are sending the received data back byte by byte. Is this what you are trying to do?

4. Can you explain how the semaphore variable is used? It still confuses me. Wouldn't:

while(tcp_semaphore)
{
;
}

in the callback function result in an endless loop if (semaphore == 1)?


Sorry if these questions are a bit silly, but I'm in the deep end as far as nichelite is concerned.

Thanks
Kyle
0 项奖励

1,105 次查看
ColdFireHot
Contributor I
Kyle,
  I am using HyperTerminal for TCP connections.  It works simple enough for me to type characters and see them echoed back.
  I'm not sure about msring as I was going to ask you the same question.  I gave some thought to how InterNiche was implementing there TCP stack and I concluded (assumed) that there is a fundamental flaw in its implementation.  The thought is; if TCP is a reliable connection then listening on a specific port number (10001 in my case) would allow for a connection to be made to another machine by sending back a locally generated port number to be used for the connection.  Once this port number is assigned and accepted then the connection is made and no other connections would be accepted for port 10001.  Since I can connect to the same TCP port from another machine while the first connection is still active then the InterNiche stack is not rejecting a TCP connection that has already been established and active.
  I think you may be right on the semaphore issue.  In a threaded application this would make sense but as it is the callback would block if the semaphore happens to be set.  I would need to establish a flag that could be used in the forground task and return from the callback in order for this to work properly.
  I was just trying to echo byte for byte back to the sender, this was a simple test to establish a connection and prove that it was working.  The final changes would collect the data coming in and either process or just pass it along to the serial port, ie TCP to Serial.
 
This probably won't help but, I have reviewed all of the documentation for the InterNiche Nichelite stack and could find no information about how to get the port to reject further requests once a connection was made.
 
No such thing as a silly question.  Only silly answers  :smileyhappy:
 
Mark
 
0 项奖励

1,105 次查看
mjbcswitzerland
Specialist V
Hi

To the port connection issue:

A connection is between two ports and there can only be one connection between the port "pair" at the same time.

If you have a listner on port x and a connection is established from port y, the port x->y is in use.

If a connection is attempted to the listener x from port z this is a different port pair and it is correct that a connection is established.

A connection will only be refused if the port number x doesn't exist (ie. no listener on it) or if the number of supported (parallel) connections to port x has been exceeded. The number of connections to a port will be defined somewhere (it is possibly a single value applied to all ports or on a port function basis [eg. a Telnet port can suppport 5, an HTTP can support 20, etc.].

If you want a listener to reject further connection attempts, it will be necessary to configure to allow only one connection per port (or to this port), or else use additional code in the corresponding listener to reject a connection attempt if there is already a connection open.

Regards

Mark Butcher

www.uTasker.com

Message Edited by mjbcswitzerland on 2007-01-1503:13 PM

0 项奖励

1,105 次查看
ColdFireHot
Contributor I
Mark,
  I think I understand now.  When Nichelite performs the callback I need to stop listening on port 10001.  This should affect the [RST,ACK] that I am after......
 
The following worked
1) Start a "SocketHolder = m_listen()"
2) On a callback the active socket will be put in msring and I need to m_close(SocketHolder)
3) Handle communications with the active socket.
4) On the passive socket close -> Rinse and repeat.
 
I did not fully test the second TCP connect attempt, but it did get rejected.  No [RST,ACK] but I did get ICMP messages "Destination unreachable (Port unreachable)".  This is right as I stopped listening.
I don't have enough info for NicheLite to set the number of active sockets to 1 for the desired port, which would probably result in the [RST,ACK] from the TCP stack.
As of now I have not found any documentation on how to implement this last feature.
 
Thanks for your insight and feedback,
Mark
 
 
0 项奖励

1,105 次查看
wyliek
Contributor I
Hi Mark

I'm still battling with this simple server application. Have you perhaps completed a working server? Some sample code would be nice to look through. Using your posted code I have been able to receive and echo back data, (Using hyperterminal) but the application does not seem to reset a connection properly. The http example code is proving to be a bit complex for me to work with.

Could you also perhaps explain how the semaphore is used?

Thanks
Kyle
0 项奖励

1,105 次查看
ColdFireHot
Contributor I
Kyle,
  Here is an updated version.  The "tcp_server_socket" is used to close the listening socket in the callback routine.  The semaphore has been removed and a flag "OpenSocket" is used to allow the TCP_check() routine to start listening again.
 
I'm no expert at this so use at your own risk   :smileyhappy:
 
Regards,
Mark
 
0 项奖励

1,105 次查看
wyliek
Contributor I
Hi there

I’m working with the freescale http server example. I have been trying to modify it to create a simple TCP server that listens on a port and echos back any data received. I have been able to achieve this by simply changing the port number from 80 to 5005, removing the functions:

freescale_http_upload_file()
and
freescale_http_erase_flash()

and modifying the function:

freescale_http_read_header()

to look like this:
{
int length, j, k;

if( freescale_http_sessions[session].keep_alive )
freescale_http_sessions[session].keep_alive--;

length = m_recv( freescale_http_sessions[session].socket, (char *)buffer, RECV_BUFFER_SIZE );

if( length 0 )
{
if( !freescale_http_sessions[session].keep_alive )
{
// freescale_http_sessions[session].state = EMG_HTTP_STATE_CLOSE;
// freescale_http_sessions[session].keep_alive = HTTP_KEEP_ALIVE_TIME;
}
return;
}
if (length>0)
{
freescale_http_sessions[session].keep_alive = HTTP_KEEP_ALIVE_TIME;

m_send(freescale_http_sessions[0].socket, (char *)buffer, length);
}

}

This seems to work very well, but today I tried modify the function freescale_http_init() as follows:

int freescale_http_init()
{
int e;

semaphore = 0;
flash_ffs_lockout = 0;

// Init flash state machine clock
//flash_init( ); REMOVE THIS

// Init session array
freescale_http_delete( );

//REMOVE THE INSTALL MENU COMMAND:
/*
// Install Menu item 'DIR' for EMG FFS
//if( install_menu( emg_ffs_dir_menu ) )
// printf( "\nCould not install DIR menu item for EMG FFS" );
*/
//REMOVE THE INSTALL MENU COMMAND:

// Init message queue for MINI_TCP socket interface
msring_init(&emg_http_msring, emg_http_msring_buf, sizeof(emg_http_msring_buf) / sizeof(emg_http_msring_buf[0]));

// Init a socket structure with our Port Number
emg_http_sin.sin_addr.s_addr = (INADDR_ANY);
emg_http_sin.sin_port = (PORT_NUMBER);

emg_http_server_socket = m_listen(&emg_http_sin, freescale_http_cmdcb, &e);
if (emg_http_server_socket == INVALID_SOCKET)
{
dprintf("error %d starting listen on emg HTTP server\n", e);
}

return SUCCESS ;
}

I find that removing the install menu command causes the program to stop functioning correctly. I am still able to connect to the TCP server but it takes at least 4 seconds after I have sent data to the server for the server to receive it. After the first load of data has been received the server is then able to receive data more quickly. However, the socket does not close properly when the close command is sent. I tried to debug this problem and found that the tcp callback function only gets called a few seconds after the first data packet is sent. Why would removing the install menu command cause this? It makes no sense to me as I am not using the menu anywhere.

Any ideas?
0 项奖励

1,105 次查看
mjbcswitzerland
Specialist V
Hi Mark

I don't actually know the Interniche details but generally you can define the number of sockets available on a port. If you can set the port to have only one socket, any received SYN frames should automatically be answered with a RST due to the fact that there are no free sockets on the port when the only one is already connected.

If you haven't done so already, check out also the uTasker stack (OS, TCP/IP, drivers and real-time simulator for the M5223X). It is free for non-commercial use, including direct support. www.uTasker.com.

There are binaries and out-of-the-box project for the DEMO board, plus tutorials - all on the web site.

Regards

Mark Butcher
0 项奖励