Embedded server

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Embedded server

Jump to solution
2,189 Views
Swapnil_Enable
Contributor III

    Hello, i have been doing the development for a Embedded server for multiple client. i developed the code.....unfortunately...no one in my surrounding have worked with MQX + RTCS + Ethernet and i am new born for it. so i need your valuable suggestion for the same, just need to confirm that what i am doing is on good path:

what i want to do:

create a server with 12 ports to connect one client each port. for data transmission and reciption.

the Server task: i have written, logic flow:

1. first i created the socket's (all 12) assign them with a predefined Port.

2. in infinte while loop

     i. child_sock = RTCS_selectall(0);

     ii. child_sock = accept(listensock[0], NULL, NULL); // similarly for others ...

          after accept RTCS_detachsock the socket

          create a new task attach the socket with RTCS_attachsock

Labels (1)
0 Kudos
1 Solution
1,000 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Swapnil,

What you are trying to implement is what usually is called Daemon Server. I developed one of these some time ago. I am attaching here. I hope helps you.

Regards,

-Garabo

View solution in original post

0 Kudos
14 Replies
1,000 Views
davidsa
Contributor I

I have copied your basic server code to my project and the problem I am having is that the while loop

continues to connect to the same IP address creating multiple connections of serverCTask. I have done this

in a Linux environment but MQX 4.1 seems to have its own unique requirements. I can't test for IP address

similarities and delete the connections. That would eat up valuable resources.

0 Kudos
1,000 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi David,

I am sorry but I would need more details about what you want to accomplish.

This server will accept connections from any client that is connected in the same LAN.

QUICK NOTE:

Make sure that you are not giving the same IP address and MAC address to the client and server.

Regards,

Garabo

0 Kudos
1,000 Views
davidsa
Contributor I

Below is a section of code. Basically what is going on when a device with for example IP 172.22.1.32 on port 512

will connect create a task result = taskcreate(0, ModBus_C_TASK, child_sock); and pass in the child client

that just connected. The while loop will loop back around and the same IP 172.22.1.32 will again connect create

another task task result = taskcreate(0, ModBus_C_TASK, child_sock); and so on. the printf "Client dispatched…"

will print every second. Constantly creating new tasks task result = taskcreate(0, ModBus_C_TASK, child_sock);…………….

listensock_one = socket(AF_INET, SOCK_STREAM, 0);//PF_INET

if (listensock_one == RTCS_SOCKET_ERROR)

{

error = RTCSERR_OUT_OF_SOCKETS;

shutdown(listensock_one, FLAG_ABORT_CONNECTION);//FLAG_CLOSE_TX);

statusWord= 0x0800;

//printf("Fg");

return;

}

BufferValue = 512; // 512 bytes send and receive

setsockopt(listensock_one, SOL_TCP,OPT_TBSIZE,&BufferValue,sizeof(BufferValue));

setsockopt(listensock_one, SOL_TCP,OPT_RBSIZE,&BufferValue,sizeof(BufferValue));

// BufferValue = TRUE;

// setsockopt(listensock_one, SOL_TCP,OPT_RECEIVE_NOWAIT,&BufferValue,sizeof(BufferValue));

// setsockopt(listensock_one, SOL_TCP,OPT_NO_NAGLE_ALGORITHM,&BufferValue,sizeof(BufferValue));

// BufferValue = 5000;//ms

// setsockopt(listensock_one, SOL_TCP,OPT_CONNECT_TIMEOUT,&BufferValue,sizeof(BufferValue));

//BufferValue = 1;//ms

//setsockopt(listensock_one, SOL_TCP,OPT_KEEPALIVE,&BufferValue,sizeof(BufferValue));

BufferValue = 100;

setsockopt(listensock_one, SOL_TCP,OPT_TIMEWAIT_TIMEOUT,&BufferValue,sizeof(BufferValue));

error = bind(listensock_one, &laddr, sizeof(laddr));

if (!error)

{

statusWord= 0x0400;

//printf("RR"); // socket initial bind, TCP READY

error = listen(listensock_one, 0);

}

else

{

shutdown(listensock_one, FLAG_ABORT_CONNECTION);//FLAG_CLOSE_TX);

statusWord= 0x0500;

//printf("Fb"); // TCP failed to bind

RTCS_detachsock(listensock_one);

return;

}

uint_16 remote_addr_len;

timedelay(250);

remote_addr_len = sizeof(remote_addr);

do

{

//child_sock = RTCS_selectall(0);

statusWord= 0x1000; //ModBusServerTask waiting to connect

child_sock = accept(listensock_one, &remote_addr, &remote_addr_len);//accept(listensock, &remote_addr, &remote_addr_len);

if (child_sock==RTCS_SOCKET_ERROR)

{

shutdown((uint_32)child_sock, FLAG_ABORT_CONNECTION);

statusWord = 0x0600; //printf("Fl"); // modbus listen socket abort error

continue;

}

else

{

printf("add: 0x%X\n %d",remote_addr.sin_addr,remote_addr.sin_port);

/////////////////////////////////////////////////////

///Grab child connected socket and pass no new task.

if (RTCS_detachsock(child_sock) == RTCS_OK)

{

printf("server child task.\n");

result = taskcreate(0, ModBus_C_TASK, child_sock);

if (result == MQX_NULL_TASK_ID)

{

shutdown(child_sock, FLAG_CLOSE_TX);

printf("\nCould not create server child task.\n\r");

}

}

else

{

printf("\nCould not create server child task.\n");

}

timedelay(1000);

printf("Client dispatched...\n\r");

}

////////////////////////////////////////////////////////

///Check linkActive flag

if(linkActive == false)

{

shutdown(listensock_one, FLAG_ABORT_CONNECTION);//FLAG_CLOSE_TX);

statusWord = 0x0900; //printf("Rv"); // modbus Restart modbus socket

return;

}

}

while( child_sock != RTCS_SOCKET_ERROR );

0 Kudos
1,000 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi David,

What you are describing is the implementation as designed for this code you posted. You can open as many connections as you want form the same IP address. This code is allowing it. The only thing that distinguish each connections are the sockets. If you one new sockets form one IP address to another then you will open as much as you allow. Just imagine that you want to have two FTP or SSH connections from the same computer to another linux computer. FTP and/or SSH server will allow it.

You could prevent to create double connections, but you need to add the logic and code to track which IP addresses had already created a success connection. This should be implemented in the server side, the code you added. Just after the accept happened.

I hope this helps you to clarify how the implementation should be done.

Regards,

Garabo

0 Kudos
1,000 Views
davidsa
Contributor I

Thanks that actually make since. So the only viable solution is the let it connect compare the IP's

and if already connected then disconnect the user?

David

0 Kudos
1,000 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi David,

Yes, you can either disconnect the current connected socket and then accept the new connection from the same IP address or you can reject the new connection if you confirm that the current connection is still alive and giving information back and forward.


Have a great day,
Garabo

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,000 Views
davidsa
Contributor I

If I delete the child_sock I do not want the child_sock, which is running on another task stops working.

Same IP address. And yes the other socket is running and exchanging data.

shutdown(child_sock, FLAG_ABORT_CONNECTION);

David

0 Kudos
1,000 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi David,

If you delete the code that creates the child then you will be able to handle only one client at the time. Again, it will depend a lot on the kind of implementation you want. This code is daemon kind implementation.


Have a great day,
Garabo

0 Kudos
1,000 Views
davidsa
Contributor I

Thanks I do understand what you are saying. Let me try to rephrase the question.

I get one connection on IP 172.22.1.5 port 0xc3d3 and I pass it to a task to run

A second connection on IP 172.22.1.5 port 0xc3d4 and this socket I shutdown since it is from the same IP

address. When I close port 0xc3d4 it also closes the first port 0xc3d3 on a completely different task.

Since the connection are from different ports why are both connections closing and is there a method to

avoid this situation?

David

0 Kudos
1,000 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi David,

The port is the one used to stablish the socket connection. You can have many channels to you IP address, those are the ports. For instance, FTP is located in the port 22. If you are receiving another connection to the port 0xC3D4 then this should be rejected by TCPIP since you don't have a socket opened in this port.

If you are closing a socket you have to make sure is the one you are deattaching and passing to the client task. Or, the accept will return you a new socket, that is the one you need to shutdown.

Best Regards,

Garabo

0 Kudos
1,000 Views
davidsa
Contributor I

Thank you for your help and telling me what is the obvious. I do understand the ports and

how all the socket connections work. I am also deleting the correct port.

Thanks for your help I will try to resolve this trying another method.

David

0 Kudos
1,001 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Swapnil,

What you are trying to implement is what usually is called Daemon Server. I developed one of these some time ago. I am attaching here. I hope helps you.

Regards,

-Garabo

0 Kudos
1,000 Views
Swapnil_Enable
Contributor III

thanks for response Garabo. u mention that u have attached some related work. but i am unable to see it. meanwhile, i have created the code what i mention above. still not sure abt the memory calculation for the task and sockets as i have to add this with my project in 512kb code memory of mk60n512 controller. please suggest what can i do to understand it. Regards, Swapnil K.

0 Kudos
1,000 Views
Luis_Garabo
NXP TechSupport
NXP TechSupport

Hi Swapnil,

It is weird that you can’t see the attachment. I can see it right there after the text of my posting. What internet explorer are you using, Firefox, Microsoft?

Regarding socket memory allocation...With the TaskAwareDebugging, you can see that every new TCP socket connection needs extra 500+4392x2+148=9432B/59.0KB=16% as follows:

MQX -> Lightweight Memory Block Summary Size (Decimal) Owner    Type

500      0x10001  TCP Control Block;RTCS/TCP

4392   0x10001  TCP Tx Window;RTCS/TCP

4392   0x10001  TCP Rx Window;RTCS/TCP

148     0x10001  TCP Send Clock;RTCS/TCP

(TCP/IP Task id is 0x10001)

The default OPT_TBSIZE and OPT_RBSIZE are 4380 bytes. If you call setsockopt() to reduce these two, for example, to a quarter like 1095 bytes, the memory usage to open a new TCP socket will drop from 16% to 4.7% as follows:

MQX -> Lightweight Memory Block Summary Size (Decimal) Owner    Type

500  ->  500   0x10001  TCP Control Block;RTCS/TCP

4392 -> 1108   0x10001  TCP Tx Window;RTCS/TCP

4392 -> 1108   0x10001  TCP Rx Window;RTCS/TCP

148  ->   84   0x10001  TCP Send Clock;RTCS/TCP

If the problem persists please set a slower number, try next:

uint_32 value;

value = 256;

setsockopt(sock, SOL_TCP,OPT_TBSIZE,&value,sizeof(value));

setsockopt(sock, SOL_TCP,OPT_RBSIZE,&value,sizeof(value));

Also, it might be possible that you need more PCBs, MSG and sockets. Could you please add the next lines just before call the function RTCS_create() just as the web_hvac does in the C:\Program Files\Freescale\Freescale MQX 3.5\demo\web_hvac\RTCS.c file?

/* runtime RTCS configuration */

_RTCSPCB_init = 4;

_RTCSPCB_grow = 2;

_RTCSPCB_max = 20;

_RTCS_msgpool_init = 4;

_RTCS_msgpool_grow = 2;

_RTCS_msgpool_max = 20;

_RTCS_socket_part_init = 4;

_RTCS_socket_part_grow = 2;

_RTCS_socket_part_max = 20;

Try this to see if you can get more resources. I hope this helps. Have a nice day.

-Garabo

0 Kudos