How can I make a multi client server with more function? - c

I am new in TCP server client program . I want to develop a application in C to authenticate client and receive data from server . I know I need to use thread to handle multiple client . But I am concern about how can I call each functions in server side via thread or any need of creating more threads in server (like worker thread to do each functions) . I have a server which has lot of function like fun1() ,fun2(),fun3(),fun4() to handle the client data .So Is it any problem or delay when I use thread ? because when multiple client come at one sec , how the server handle this case ? I develop a logic like
server fun
{
//thread function calling fun1()
}
void *fun1(void *arg)
{
fun2()
pthread_exit((void*)xx)
}
fun2()
{
fun3()
}
fun3()
{
}

When you are using C you have to use the function accept for incoming connections. accept is a blocking function, so it waits until a connection is established. The return parameter of this function is a socket.
So your next statement after accept should be a creation of a thread with the input parameter of the socket. In your thread you can call your functions fun1,fun2,...
Of course there is a little delay but it's only milliseconds. When multiple clients are going to connect, they are queued.
The advantage of a parallel Server instead of a serial server is that one client can't block your service.

Related

TCP Server on LwIP raw API - question about tcp_close and accept callback

I'm using this simple echo-server as an example.
It creates a listening connection, receives a packet, sends it back and then closes the connection.
In the initialization function, accept callback is registered in lwip like this:
void
echo_init(void)
{
echo_pcb = tcp_new();
...
echo_pcb = tcp_listen(echo_pcb);
tcp_accept(echo_pcb, echo_accept);
Connection is closed by the server after each echo session, like this:
void
echo_close(struct tcp_pcb *tpcb, struct echo_state *es)
{
tcp_arg(tpcb, NULL);
tcp_sent(tpcb, NULL);
tcp_recv(tpcb, NULL);
tcp_err(tpcb, NULL);
tcp_poll(tpcb, NULL, 0);
if (es != NULL)
{
mem_free(es);
}
tcp_close(tpcb);
Documentation says that tcp_close will free pcb structure. All of the callbacks that are used for tcp server are registered with this structure.
But when client sends new packet and starts a new connection, accept callback is called! Even though tcp_accept(echo_pcb, echo_accept); (i.e. callback registration) is done only once in the init function and that echo_pcb structure is already freed after tcp_close.
So I'm confused. Why all the other callbacks are registered multiple times but accept is registered only once? Is it okay to do it like this?
Okay, so according to this answer to the same question on the lwip mailing list, that is correct behaviour. tcp_accept registers callback for a port and it won't be unregistered when tcp_close is called.

How to send measurements to a server and receive data from sensor at the same time?

I'm trying to process data from my sensors, and simultaneously, upload data to the server(Thingspeak).
The problem is, whenever server connection(using wifi) ends(and i couldn't find a way to extend my session to prevent timeout), reconnecting takes time and during that time, i can't process the data from the sensors, resulting occasional holes in my data.
I heard there's some way of resolving this problem by using callback functions, somehow making the core to wait for the response from the server each time I try to connect to server, and at the same time, process the data i'm getting from the sensor.
My code right now is like this
loop
{
while(now==prev)
{
processdata;
}
prev=now;
count++;
if(count==15)
{
count=0;
senddata();
}
}
senddata()
{
if(!serverconnected)
{
if(!send connect request()) error message; //after this function calls,
if(!receive connection confirmed()) error message; //takes too long time until this function finishes executing.
}
send data.
}
actual function names for the commented parts are
client.connect(host, port)
client,verify(fingerprint, host)
functions from
WiFiClientSecure.h
is there any way to use callback methods to fix this issue?
While searching for the solution, I found the following header file
espconn.h
which seems to have callback functions that I can use... but I'm not sure if this is using different methods of establishing wifi connections to the server, nor how to use the functions itself.
As long as you use rest api you will not be able to comfortably keep the session alive. So you better have websocket or MQTT like protocol where session is handled by them an you will be only responsible to push the data to server instantly on any time.
This link describes how an mqtt client connection to be done on Thingspeak and pushing the data to it.
Some code cuts from the link :
#include <PubSubClient.h>
WiFiClient client;
PubSubClient mqttClient(client);
const char* server = "mqtt.thingspeak.com";
mqttClient.setServer(server, 1883);

How to listen to a socket and connect to a different socket(same ip address but different port number) in a same c program

Hi I am figuring out a way to listen to a socket and connect to a different socket(on same ip but different port number) simultaneously in the same program.when I listen to a socket then it keeps blocking until it receives some message so I am not able to listen and connect simultaneously.
I actually need to simulate exchange of LSP packets between different routers. So I am writing a program to simulate a router so as to run it n(number of routers)times.
Could anyone please share on how to proceed ??
If I understood your problem correctly, one of these might help.
Multi-thread or Multi-process
Basically, when you receive a client you can process a client separately in a separate thread or in a new process. You will be able to receive incoming connections and connect to new clients from other sources while processing the ones who are already connected.
Pseudo Code:
main() {
while(1) {
accept client
/*
After the fork or creation of the new thread, the loop goes back to
accepting clients while connected clients are being processed.
*/
fork or create new thread passing and client socket to it
}
}
processClient() {
do whatever you need to do...
}
Select
Select is another good way of doing non-blocking sockets. Select basically waits for data to come (ie. data, new client requests) to the server and processes them one-by-one. The server will not block on accept as it will wait until it receives something before processing it.
Psuedo Code:
main() {
while(1) {
wait on select
if new client {
accept it
}
for client in clients {
if client has data {
process it
}
}
}
}
ePoll (if you're in Linux)
ePoll is similar to Select only it can handle WAY more clients and it's a lot sexier.
Here's a repo that has each of those. My code isn't perfect here as it was a project that I did while in school.
https://github.com/koralarts/ServerBenchmarking

Can't figure out how to implement threads in my client-server model

I have a small server-client application that doesn't do very much (a client connects to the server, sends a number trough a pipe and receives another number).
But it only works with one connection at a time (While a client is connected, no other client has access to the server)
I want to make it possible for multiple clients to connect to the server at one time, and I plan to do this with worker threads.
Obs:
#define CONNECT_NAMEDPIPE "\\\\.\\pipe\\ClientToServer"
Server:
HANDLE namedPipe = CreateNamedPipe (CONNECT_NAMEDPIPE,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
2,
sizeof(MinMax),
sizeof(NumberList),
0, // timeout
NULL);
if (namedPipe == INVALID_HANDLE_VALUE) {
printf("Unable to create named pipe\r\nServer closing\r\n");
printf("CreateNamedPipe failed, GLE=%d.\r\n", GetLastError());
} // Error unable create pipe
else {
printf("Server created\r\n");
printf("Awaiting connection\r\n");
ConnectNamedPipe(namedPipe, NULL);
etc ...
}
So the server waits on ConnectNamedPipe until a client connects, then is unavailable for any other connections.
If I'd like to enable multiple connections, how should I create the worker threads ?
Should every connection attempt create a new pipe (with a new pipe name / path - CONNECT_NAMEDPIPE can't be used for all)
How do I know when someone else is trying to connect ? Where should my threads be ? I'm stuck.
I think Berkeley sockets are better suited for this. If you must go with pipes, something like this could work:
The client sends a connection request through the main named pipe to the control thread.
The server creates (or fetches from a pool) a worker thread that listens on another, unique pipe.
The control thread answers with the name of this new pipe.
The client closes the control pipe and sends real request data to the new pipe.
The worker thread reads the request, processes it, and sends back the response.
Meanwhile the control thread is ready to read another connection request from another client.

Multi-clients on a server

For an application in C, i need to response more than one clients.
I setup the connection with a code like,
bind(...);
listen(...);
while(1){
accept(...);//accept a client
recv(...);//receive something
send(...);//send something to client
bzero(buf);//clear buffer
}
This works great when i have only one client. Other clients also can connect to the server but although they command something, server does not response back to clients who connected after the first client. How can i solve this problem?
Write a server using asynchronous, nonblocking connections.
Instead of a single set of data about a client, you need to create a struct. Each instance of the struct holds the data for each client.
The code looks vaguely like:
socket(...)
fcntl(...) to mark O_NONBLOCK
bind(...)
listen(...)
create poll entry for server socket.
while(1) {
poll(...)
if( fds[server_slot].revents & POLLIN ) {
accept(...)
fcntl(...) mark O_NONBLOCK
create poll and data array entries.
}
if( fds[i].revents & POLLIN ) {
recv(...) into data[i]
if connection i closed then clean up.
}
if( fds[i].revents & POLLOUT ) {
send(...) pending info for data[i]
}
}
If any of your calls return the error EAGAIN instead of success then don't panic. You just try again later. Be prepared for EAGAIN even if poll claims the socket is ready: it's good practice and more robust.
i need to response more than one clients.
Use Threading.
Basically you want your main thread to only do the accept part, and then handle the rest to another thread of execution (which can be either a thread or a process).
Whenever your main thread returns from "accept", give the socket descriptor to another thread, and call accept again (this can be done with fork, with pthread_create, or by maintaining a thread pool and using synchronization, for instance condition variables, to indicate that a new client has been accepted).
While the main thread will handle possible new clients incoming, the other threads will deal with the recv/send.

Resources