Merhaba,
Bu konuyu buraya gondermek dogrumu bilmiyorum ama
liste uyelerinin bu konuda tecrubesi oldugunu
dusunerek yaziyorum.
Ben multi-threaded calisan bir 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 sefer bagli
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); if(n == 0) { threads[tid].clients[i] = 0; printf("client %d closed connection \n", threads[tid].clients[i]); } else if(n < 0) { threads[tid].clients[i] = 0; printf("client %d closed connection \n", threads[tid].clients[i]); } else { printf("\n %d bytes received from %d\n", n, threads[tid].clients[i]); } } } }*/ } } int choose_thread() { int i=MAX_THREAD-1; int min = 0; while(i > -1) { if(threads[i].client_count < threads[i-1].client_count) { min = i; break; } i--; } return min; } int main() { char c; struct sockaddr_in srv, cli; int clifd; int tid; int i; int choosen; if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("sockfd\n"); exit(1); } bzero(&srv, sizeof(srv)); srv.sin_family = AF_INET; srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons(PORT); if( bind(listenfd, (struct sockaddr *) &srv, sizeof(srv)) < 0) { perror("bind\n"); exit(1); } listen(listenfd, 1); /* create threads */ for(i = 0; i < MAX_THREAD; i++) { pthread_create(&threads[i].tid, NULL, &thread_init_func, (void *) i); threads[i].client_count = 0; } for( ; ; ) { clifd = accept(listenfd, NULL, NULL); /*nonblock(clifd);*/ pthread_mutex_lock(&new_connection_mutex); choosen = choose_thread(); threads[choosen].clients[threads[choosen].client_count] = clifd; threads[choosen].client_count++; printf("choosen: %d\n", choosen); for(i = 0; i < MAX_THREAD; i++) { printf("threads[%d].client_count:%d\n", i, threads[i].client_count); } pthread_mutex_unlock(&new_connection_mutex); } return 0; }
--------------------------------------------------------------------- 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