[freebsd] multi-threaded server
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
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
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