分类:
2010-03-08 22:17:06
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 8764
#define BACKLOG 5
int status = -1;
struct SockFD
{
int sock_fd;
struct SockFD * next;
};
struct SockFD * table = 0;
pthread_mutex_t mutex;
void * server(void * args)
{
pthread_mutex_init(&mutex , 0);
int svr_fd = socket(PF_INET , SOCK_STREAM , 0);
if (svr_fd == -1)
{
perror("server socket");
pthread_exit(&status);
}
struct sockaddr_in svrAddr;
svrAddr.sin_family = PF_INET;
svrAddr.sin_port = htons(SERVER_PORT);
svrAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(svr_fd , (struct sockaddr *)&svrAddr , sizeof(svrAddr)) == -1)
{
perror("bind");
close(svr_fd);
pthread_exit(&status);
}
if (listen(svr_fd , BACKLOG) == -1)
{
perror("listen");
close(svr_fd);
pthread_exit(&status);
}
int fd = 0;
struct sockaddr_in addr;
unsigned int size = sizeof(addr);
while ((fd = accept(svr_fd , (struct sockaddr *)&addr , &size)) != -1)
{
pthread_mutex_lock(&mutex);
struct SockFD * node = (SockFD *)malloc(sizeof(SockFD));
memset(node , 0x00 , sizeof(SockFD));
node->sock_fd = fd;
if (table == 0)
table = node;
else
{
node->next = table;
table = node;
}
pthread_mutex_unlock(&mutex);
}
close(svr_fd);
pthread_mutex_destroy(&mutex);
return 0;
}
void * reader(void * args)
{
int ret = 0;
fd_set reader_fd;
while (true)
{
struct SockFD * sock_list = 0;
int max_fd = 0;
pthread_mutex_lock(&mutex);
struct SockFD * ptr = table;
for (;ptr; ptr = ptr->next)
{
if (ptr->sock_fd > max_fd)
max_fd = ptr->sock_fd;
FD_SET(ptr->sock_fd , &reader_fd);
struct SockFD * node = (SockFD *)malloc(sizeof(SockFD));
memset(node , 0x00 , sizeof(SockFD));
node->sock_fd = ptr->sock_fd;
if (sock_list == 0)
sock_list = node;
else
{
node->next = sock_list;
sock_list = node;
}
}
pthread_mutex_unlock(&mutex);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 50;
int ret = select(max_fd + 1 , &reader_fd , 0 , 0 , &timeout);
if (ret > 0)
{
struct SockFD * ptr = sock_list;
for (;ptr;ptr = ptr->next)
{
if (FD_ISSET(ptr->sock_fd , &reader_fd))
{
char buffer[256] = {0};
if (read(ptr->sock_fd , buffer , 50) <= 0)
{
close(ptr->sock_fd);
break;
}
printf("%s\n" , buffer);
}
}
}
struct SockFD * pNode = sock_list;
while (pNode)
{
pNode = pNode->next;
free(sock_list);
sock_list = pNode;
}
}
return 0;
}
void * writer(void * args)
{
int ret = 0;
fd_set writer_fd;
int max_fd = 0;
while (true)
{
struct SockFD * sock_list = 0;
pthread_mutex_lock(&mutex);
struct SockFD * ptr = table;
for (;ptr; ptr = ptr->next)
{
if (ptr->sock_fd > max_fd)
max_fd = ptr->sock_fd;
FD_SET(ptr->sock_fd , &writer_fd);
struct SockFD * node = (SockFD *)malloc(sizeof(SockFD));
memset(node , 0x00 , sizeof(SockFD));
node->sock_fd = ptr->sock_fd;
if (sock_list == 0)
sock_list = node;
else
{
node->next = sock_list;
sock_list = node;
}
}
pthread_mutex_unlock(&mutex);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 50;
int ret = select(max_fd + 1 , 0 , &writer_fd , 0 , &timeout);
if (ret > 0)
{
struct SockFD * ptr = sock_list;
for (;ptr;ptr = ptr->next)
{
if (FD_ISSET(ptr->sock_fd , &writer_fd))
{
char buffer[256] = {0};
sprintf(buffer , "response: from server.");
if (write(ptr->sock_fd , buffer , 50) <= 0)
{
close(ptr->sock_fd);
break;
}
}
}
}
struct SockFD * pNode = sock_list;
while (pNode)
{
pNode = pNode->next;
free(sock_list);
sock_list = pNode;
}
}
return 0;
}
void * client(void * args)
{
int fd = 0;
if ((fd = socket(PF_INET , SOCK_STREAM , 0)) == -1)
{
perror("socket");
pthread_exit(&status);
}
struct sockaddr_in addr;
addr.sin_port = htons(SERVER_PORT);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_family = PF_INET;
if (connect(fd , (struct sockaddr *)&addr , sizeof(addr)) == -1)
{
perror("connect");
pthread_exit(&status);
}
char buffer[256] = {0};
sprintf(buffer , "request: from client.");
write(fd , buffer , 50);
memset(buffer , 0x00 , 256);
read(fd , buffer , 50);
printf("%s\n" , buffer);
close(fd);
return 0;
}
int main(int argc , char ** argv)
{
pthread_t svr_tid = 0;
pthread_t reader_tid = 0;
pthread_t writer_tid = 0;
pthread_t clt_tid1 = 0;
pthread_t clt_tid2 = 0;
printf("starting server......\n");
if (pthread_create(&svr_tid , 0 , server , 0) != 0)
{
perror("pthread_create");
return -1;
}
if (pthread_create(&reader_tid , 0 , reader , 0) != 0)
{
perror("pthread_create");
return -1;
}
if (pthread_create(&writer_tid , 0 , writer , 0) != 0)
{
perror("pthread_create");
return -1;
}
sleep(5);
printf("starting client......\n");
if (pthread_create(&clt_tid1 , 0 , client , 0) != 0)
{
perror("pthread_create");
return -1;
}
if (pthread_create(&clt_tid2 , 0 , client , 0) != 0)
{
perror("pthread_create");
return -1;
}
pthread_join(svr_tid , 0);
pthread_join(reader_tid , 0);
pthread_join(writer_tid , 0);
pthread_join(clt_tid1 , 0);
pthread_join(clt_tid2 , 0);
return 0;
}