Hi I'm creating a socket server in Linux using pthreads. I was just wondering, how does the server send specific messages to its clients (for instance, a PM) if each is in its own standalone thread?
communism 0 Newbie Poster
Lucaci Andrew 140 Za s|n
Well you could easily acomplish that by using some Linux C functions:
send: Click Here (also in your terminal man send)
recv: Click Here (also in your terminal man recv)
Here's a tutorial on that:
Click Here
Follow the steps Beej puts there, and you'll be fine.
Edited by Lucaci Andrew
Lucaci Andrew 140 Za s|n
Here's a quick example that I have cooked up. It's not bright and perhaps with many buggs (I admit, done in a jiffy :) ), but it should get you started:
What does this program do?
1. Server starts up the process by creating the connections, with a fixed (as a console argument) number of clients to connect to it, such as a fix number as its port.
2. Clients connect to the server.
3. Clients send a random number between 1 and 100, and they get back that numbered tripled.
4. Server waits for the number, triples it, and sends it back. Also, it has a counter, which will be incremented by each thread as it gets in the worker
function.
Easy-peasy:
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
//usefull structure when dealing with threads and sockets
typedef struct pd_t{
int sock;
pthread_t t;
}pd_t;
//some global variables
pd_t* t;
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
int counter=0;
//initialization function
void init(int max){
t=malloc (sizeof (pd_t) * max);
}
void* worker (void* arg){
int index=(int) arg, sock=t[index].sock;
//using threads
printf("Thread %d increments the counter.\n", index);
pthread_mutex_lock (&mtx);
counter++;
printf("The value of counter is %d.\n", counter);
pthread_mutex_unlock (&mtx);
//using socket communication
int number;
if (recv(sock, &number, sizeof(int), 0)<0) {perror ("Received"); exit(1);}
printf("Received number: %d.\n", ntohl(number));
number=htonl(ntohl(number)*3);
if (send(sock, &number, sizeof(int), 0)<0) {perror ("Sent"); exit(1);}
printf("Sent number: %d.\n", ntohl(number));
return NULL;
}
int main(int argc, char* argv[]){
int max, i, rvsock, sock, index=0;
unsigned short port;
sscanf(argv[1], "%hd", &port);
sscanf(argv[2], "%d", &max);
init(max);
rvsock=socket(AF_INET, SOCK_STREAM, 0);
if (rvsock<0){perror("RVSock: ");exit(1);}
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
memset(&server_addr, 0, sizeof(server_addr)); //fill up the space with 0's
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
//the error checking is crucial
if (bind (rvsock, (struct sockaddr*) &server_addr, sizeof(server_addr))<0) {
perror("Bind"); //tries to open a rande-vous socket for connection
exit(1);
}
if (listen(rvsock, max)<0) {
perror ("Listen"); //listens for 'max' clients
exit(1);
}
printf("Now I'm waiting for clients to connect.\n");
unsigned int length;
while(1){
if (index==max) break;
sock=accept(rvsock, (struct sockaddr*) &client_addr, &length);
if (sock<0) {perror ("Client accept: "); break;}
t[index].sock=sock;
pthread_create(&t[index].t, NULL, worker, (void*)index);
index++;
}
//joins the threads
for (i=0;i<max;i++){
pthread_join (t[i].t, NULL);
}
printf("The counter now has the value of %d.\n", counter);
free (t);
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
int main(int args, char* argv []){
unsigned short port;
sscanf(argv[1], "%hd", &port);
srand (time (0));
int number=rand()%100+1, ret, sock;
sock=socket(AF_INET, SOCK_STREAM, 0);
if (sock<0){
perror("Sock: ");
exit(1);
}
struct sockaddr_in saddr;
memset (&saddr, 0, sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_addr.s_addr= inet_addr("127.0.0.1"); //local ip
saddr.sin_port=htons(port);
//connects to the server
ret=connect (sock, (struct sockaddr*) &saddr, sizeof(saddr));
if (ret<0){
perror("Connect: ");
exit(1);
}
number=htonl(number); //converts to network standard endian notation;
if (send(sock, &number, sizeof(int), 0)<0){
perror("Sent");
exit(1);
}
printf("Sent number %d.\n", ntohl(number));
if (recv(sock, &number, sizeof(int), 0)<0){
perror("Receive: ");
exit(1);
}
printf("Received number %d.\n", ntohl(number));
close (sock);
return 0;
}
Compiling:
$ gcc -Wall -o server server.c -lpthread
$ gcc -Wall -o client client.c
Runnin + output:
1. Server's terminal:
$ ./server 12345 2
Now I'm waiting for clients to connect.
Thread 0 increments the counter.
The value of counter is 1.
Received number: 65.
Sent number: 195.
Thread 1 increments the counter.
The value of counter is 2.
Received number: 14.
Sent number: 42.
The counter now has the value of 2.
Client's terminal:
$ ./client 12345
Sent number 65.
Received number 195.
$ ./client 12345
Sent number 14.
Received number 42.
Run server than client.
Edited by Lucaci Andrew
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.