Blame |
Last modification |
View Log
| RSS feed
/*
C socket server example, handles multiple clients using threads */
#include<stdio.h>
#include<string.h> //strlen
#include<stdlib.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>
#//write
#include<pthread.h>
//for threading , link with lpthread
#define PORT 3210
//the thread function
void *connection_handler
(void *);
int is_connected
= 0;
int ncalls
=0;
int writesock
(int sock
, char *msg
, int len
){
int hdr
[2];
hdr
[0]=ncalls
++;
hdr
[1]= len
+ 8;
write
(sock
, hdr
, 8);
return write
(sock
, msg
, len
);
}
int main
(int argc
, char *argv
[]) {
int socket_desc
, client_sock
, c
, *new_sock
=NULL
;
struct sockaddr_in server
, client
;
//Create socket
socket_desc
= socket
(AF_INET
, SOCK_STREAM
, 0);
if (socket_desc
== -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.
sin_family = AF_INET
;
server.
sin_addr.
s_addr = INADDR_ANY
;
server.
sin_port = htons
( PORT
);
//Bind
if( bind
(socket_desc
,(struct sockaddr
*)&server
, sizeof(server
)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen
(socket_desc
, 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c
= sizeof(struct sockaddr_in
);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c
= sizeof(struct sockaddr_in
);
while( (client_sock
= accept
(socket_desc
, (struct sockaddr
*)&client
, (socklen_t
*)&c
)) )
{
puts("Connection accepted");
pthread_t sniffer_thread
;
if (is_connected
){
char message
[0xFF]="Only one client can connect. Disconnect it first!";
perror(message
);
writesock
(client_sock
, message
, strlen(message
));
close
(client_sock
);
continue;
}
new_sock
= (int *) malloc(1);
*new_sock
= client_sock
;
if( pthread_create
( &sniffer_thread
, NULL
, connection_handler
, (void*) new_sock
) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock
< 0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *daq_handler
(void *data
){
int s
= pthread_setcancelstate
(PTHREAD_CANCEL_ENABLE
, NULL
);
//Get the socket descriptor
int sock
= *(int*)data
;
char msg
[0xFF];
int cnt
=0;
while (1){
sprintf(msg
, "daq_handler %d %d", sock
, cnt
++);
int error
= 0;
socklen_t len
= sizeof (error
);
int retval
= getsockopt
(sock
, SOL_SOCKET
, SO_ERROR
, &error
, &len
);
if (retval
!=0 || error
!=0) break;
writesock
(sock
, msg
, strlen(msg
));
sleep
(5);
}
printf("Exiting thread %d", sock
) ;
}
/*
* This will handle connection for each client
* */
void *connection_handler
(void *socket_desc
) {
//Get the socket descriptor
int sock
= *(int*)socket_desc
;
int read_size
;
char *message
, client_message
[2000];
is_connected
= 1;
//Send some messages to the client
message
= "Info from connection handler\n";
writesock
(sock
, message
, strlen(message
));
//Receive a message from client
pthread_t daq_thread
= 0;
while( (read_size
= recv
(sock
, client_message
, 2000 , 0)) > 0 )
{
//Send the message back to client
int * hdr
= (int *) client_message
;
char *msg
= &client_message
[8];
printf("Received %d bytes RECID = %d LEN %d\n",read_size
, hdr
[0], hdr
[1]);
switch (hdr
[0]){
case 0:
hdr
[0]= sock
;
if( pthread_create
( &daq_thread
, NULL
, daq_handler
, (void*) &client_message
) < 0)
{
perror("could not create daq thread");
break ;
}
break;
case 3:
if (daq_thread
) {
pthread_cancel
(daq_thread
);
daq_thread
= 0;
}
break;
default: break;
}
writesock
(sock
, msg
, strlen(msg
));
}
if(read_size
== 0)
{
puts("Client disconnected");
fflush(stdout
);
}
else if(read_size
== -1)
{
perror("recv failed");
}
if (daq_thread
) {
pthread_cancel
(daq_thread
);
daq_thread
= 0;
}
//Free the socket pointer
free(socket_desc
);
socket_desc
= 0;
is_connected
= 0;
return 0;
}