[freebsd] multi-threaded server

2005-03-10 Başlik Parahat Melayev



Merhaba,
Bu konuyu buraya gondermek dogrumu bilmiyorum ama 

liste uyelerinin bu konuda tecrubesi oldugunu 
dusunerek yaziyorum.

Ben multi-threaded calisanbir TCP server 
yazmak istiyorum.
Ve her threadin server bagli 100er client'in isiyle 
ugrasmasini istiyorum.

Ekteki kodda shu ana kadar bu dusuncemi uygulamaya 
calistigim kodu
gorebilirsiniz.

Gelelim sorunlarima.
- thread'e 1 client atandiktan sonra thread 
rutinindeki while'in donmesi 
duruyor. ama hala o baglanan client'tan gelen 
verileri okuyabiliyor.

-socketin blocking oldugunu dusunerek nonblocking 
yaptigimda client'tan
data geldikten sonra sonra tekrar okumaya 
calistigimda -1 aliyorum.
-her thread'e 1er client atandiktan sonra baglanan 
clientlarin isleri 
yapilamiyor. yani recv ile gelen datayi 
alamiyorum.

- thread rutinin icinde select(2) kullanmaya 
calistim fakat bu seferbagli 
clientlardan recv ile data alamiyorum.

bos zamaniniz olursa, ilgilenirseniz 
sevinirim.
nerede hata yapiyor olabilecegimi bir turlu 
cikartamadim...

iyi calismalar,
parahat



#include stdio.h
#include pthread.h
#include sys/timeb.h
#include sys/select.h
#include sys/socket.h
#include sys/types.h
#include sys/wait.h
#include netinet/in.h
#include string.h
#include fcntl.h
#include signal.h
#include errno.h

#define MAX_CLIENT_PER_THREAD 100
#define MAX_THREAD 2
#define PORT 3355

int listenfd;
int which_thread = 0;

typedef struct {
pthread_t tid;
int tnumber;
long client_count;
int clients[MAX_CLIENT_PER_THREAD];
} Thread;

pthread_cond_t new_connection_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t new_connection_mutex = PTHREAD_MUTEX_INITIALIZER;


Thread threads[MAX_THREAD];

void nonblock(int sockfd)
{
int opts;
opts = fcntl(sockfd, F_GETFL);
if(opts  0)
{
perror(fcntl(F_GETFL)\n);
exit(1);
}
opts = (opts | O_NONBLOCK);
if(fcntl(sockfd, F_SETFL, opts)  0) 
{
perror(fcntl(F_SETFL)\n);
exit(1);
}
}

void *thread_init_func(void *arg)
{
int tid = (int) arg;

fd_set fdset;
int highfd = 2;
int readsocks;
int i;
char buffer[1024];
int n;

printf(thread %d created\n, tid);
printf(sizeof thread.clients: %d\n, sizeof(threads[tid].clients));
memset( (int *) threads[tid].clients, 0, sizeof(threads[tid].clients));

while(1)
{
printf(thread %d running, client count: %d\n, tid, 
threads[tid].client_count);
sleep(3);

for(i = 0; i  threads[tid].client_count; i++)
{
if(threads[tid].clients[i] != 0)
{
n = recv(threads[tid].clients[i], buffer, 1023, 
0);
if(n == 0)
{
threads[tid].clients[i] = 0;
threads[tid].client_count--;
printf(client %d closed connection 
0\n, threads[tid].clients[i]);
}
else if(n  0)
{
threads[tid].clients[i] = 0;
threads[tid].client_count--;
printf(client %d closed connection 
-1\n, threads[tid].clients[i]);
}
else {
printf(\n %d bytes received from 
%d\n, n,
threads[tid].clients[i]);
}
}
}

/*FD_ZERO(fdset);
for(i = 0; i  threads[tid].client_count; i++)
{
if(threads[tid].clients[i] != 0)
{
FD_SET(threads[tid].clients[i], fdset);
if(threads[tid].clients[i]  highfd)
highfd = threads[tid].clients[i];
}
}

readsocks = select(highfd+1, fdset, NULL, NULL, 0);

if(readsocks  0)
{
perror(select\n);
exit(1);
}
else if(readsocks == 0)
{
printf(.);
}
else {
for(i = 0; i  threads[tid].client_count; i++)
{
if(FD_ISSET(threads[tid].clients[i], fdset))
{
n = recv(threads[tid].clients[i], 
buffer, 1023, 0);

Re: [freebsd] multi-threaded server

2005-03-10 Başlik Murat Balaban

Selam,
Gayet alengirli bir sahaya ilk adiminizi atmis bulunmaktasiniz :)

 - thread'e 1 client atandiktan sonra thread rutinindeki while'in donmesi 
 duruyor. ama hala o baglanan client'tan gelen verileri okuyabiliyor.

while'in donmesi duruyor derken neyi kastediyorsunuz? while'dan mi cikiyor
program takiliyor mu? 1. durumda kodun bir yerinde ya return ya da break
vardir, ikinci durumda da soket blocking mode'da oldugu icin buffer'inda
veri olmayan bir descriptor'da block olmustur.

 -socketin blocking oldugunu dusunerek nonblocking yaptigimda client'tan
  data geldikten sonra sonra tekrar okumaya calistigimda -1 aliyorum.

errno ne?

 -her thread'e 1er client atandiktan sonra baglanan clientlarin isleri 
 yapilamiyor. yani recv ile gelen datayi alamiyorum.

recv ya hata doner, donmuyorsa da socket buffer'da veri yoktur.

 - thread rutinin icinde select(2) kullanmaya calistim fakat bu sefer bagli 
 clientlardan recv ile data alamiyorum.

Bence Ricahrd Stevens'in Unix Network Programming kitabini heen edinin
ve initial kisimlarini okuyun.

Ikinci tavsiyem de multithreaded bir server dizayni yerine, multiprocess
ve shared memory, pipe, message queue gibi IPC mekanizmalarini kullan
diginiz bir server dizayn edin. Multithreaded bir server programlamak,
gerektirdigi dikkat ve istedigi uzmanliktan dolayi su an icin sizin
icin bayagi basagrisi olabilir.

Murat

-
Cikmak icin, e-mail: [EMAIL PROTECTED]
Liste arsivi: http://lists.enderunix.org ve 
http://www.mail-archive.com/freebsd@lists.enderunix.org
Turkiye'nin ilk FreeBSD kitabi: http://www.acikkod.com/freebsd.php




Re: [freebsd] multi-threaded server

2005-03-10 Başlik Parahat Melayev
ya uykusuzluktan galiba :D
recv (man page-den okudugum kadariyla) nonblocking socketlerde bufferde
birsey bulamayinca errno olarak EAGAIN donduruyormus
bende socketi kapatiyormusum

errno'ya dikkatimi cektiginiz icin cok tesekkur ederim Murat bey

pratikte denemek kaldi...



- Original Message - 
From: Murat Balaban [EMAIL PROTECTED]
To: freebsd@lists.enderunix.org
Sent: Thursday, March 10, 2005 12:25 PM
Subject: Re: [freebsd] multi-threaded server



 Selam,
 Gayet alengirli bir sahaya ilk adiminizi atmis bulunmaktasiniz :)

  - thread'e 1 client atandiktan sonra thread rutinindeki while'in donmesi
  duruyor. ama hala o baglanan client'tan gelen verileri okuyabiliyor.

 while'in donmesi duruyor derken neyi kastediyorsunuz? while'dan mi cikiyor
 program takiliyor mu? 1. durumda kodun bir yerinde ya return ya da break
 vardir, ikinci durumda da soket blocking mode'da oldugu icin buffer'inda
 veri olmayan bir descriptor'da block olmustur.

  -socketin blocking oldugunu dusunerek nonblocking yaptigimda client'tan
   data geldikten sonra sonra tekrar okumaya calistigimda -1 aliyorum.

 errno ne?

  -her thread'e 1er client atandiktan sonra baglanan clientlarin isleri
  yapilamiyor. yani recv ile gelen datayi alamiyorum.

 recv ya hata doner, donmuyorsa da socket buffer'da veri yoktur.

  - thread rutinin icinde select(2) kullanmaya calistim fakat bu sefer
bagli
  clientlardan recv ile data alamiyorum.

 Bence Ricahrd Stevens'in Unix Network Programming kitabini heen edinin
 ve initial kisimlarini okuyun.

 Ikinci tavsiyem de multithreaded bir server dizayni yerine, multiprocess
 ve shared memory, pipe, message queue gibi IPC mekanizmalarini kullan
 diginiz bir server dizayn edin. Multithreaded bir server programlamak,
 gerektirdigi dikkat ve istedigi uzmanliktan dolayi su an icin sizin
 icin bayagi basagrisi olabilir.

 Murat

 -
 Cikmak icin, e-mail: [EMAIL PROTECTED]
 Liste arsivi: http://lists.enderunix.org ve
http://www.mail-archive.com/freebsd@lists.enderunix.org
 Turkiye'nin ilk FreeBSD kitabi: http://www.acikkod.com/freebsd.php





-
Cikmak icin, e-mail: [EMAIL PROTECTED]
Liste arsivi: http://lists.enderunix.org ve 
http://www.mail-archive.com/freebsd@lists.enderunix.org
Turkiye'nin ilk FreeBSD kitabi: http://www.acikkod.com/freebsd.php