|
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/[email protected] Turkiye'nin ilk FreeBSD kitabi: http://www.acikkod.com/freebsd.php

