Zirconi

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一个采用POSIX线程实现的简易时间服务器,服务端口为4321,客户使用Telnet连上就能看到欢迎消息以及当前服务器时间。

采用主线程accept,然后新建线程处理连接的结构。

代码中自定义了一个结构体struct client_info作为传入每个线程的参数,包含客户的连接fd,客户的sockaddr信息,用于回显消息。

代码如下:

 1 #include <unistd.h>
 2 #include <pthread.h>
 3 #include <sys/socket.h>
 4 
 5 #include <arpa/inet.h>
 6 #include <netinet/in.h>
 7 
 8 #include <stdio.h>
 9 #include <stdlib.h>
10 #include <string.h>
11 #include <errno.h>
12 
13 #define SERV_PORT 4321
14 
15 struct client_info
16 {
17     int                clientfd;
18     struct sockaddr_in clientaddr;
19     socklen_t          clientlen;
20 };
21 
22 void
23 rep_err(const char *msg)
24 {
25     fprintf(stderr, "%s\n", msg);
26     perror("TIME_SERVER");
27     exit(-1);
28 }
29 
30 void *slaver(void *);
31 
32 int
33 main(int argc, char *argv[])
34 {
35     pthread_t          tid;
36     int                listenfd, connfd, err;
37     struct sockaddr_in servaddr, clientaddr;
38     socklen_t          clientlen;
39     struct client_info *info;
40     if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
41         rep_err("SOCKET");
42 
43     memset(&servaddr, 0, sizeof(servaddr));
44     servaddr.sin_family = AF_INET;
45     servaddr.sin_port = htons(SERV_PORT);
46     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
47 
48     if((err = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0)
49         rep_err("BIND");
50 
51     if((err = listen(listenfd, 128)) < 0)
52         rep_err("LISTEN");
53 
54     for(;;)
55     {
56         clientlen = sizeof(clientlen);
57         if((connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientlen)) <=0)
58             rep_err("ACCEPT");
59 
60         info = (struct client_info *)malloc(sizeof(struct client_info));
61         info->clientfd = connfd;
62         info->clientaddr = clientaddr;
63         info->clientlen = clientlen;
64 
65         pthread_create(&tid, NULL, slaver, (void *)info);
66     }
67 
68     exit(0);
69 }
70 
71 
72 void *
73 slaver(void *info)
74 {
75     pthread_detach(pthread_self());
76 
77     char   buffer[256];
78     char   buf[64];
79     time_t now;
80     time(&now);
81     struct client_info *cinfo = (struct client_info *)info;
82 
83     snprintf(buffer, 256, "Welcome %s , from port %d\nNOW IS:\n%s",
84             inet_ntop(AF_INET, &((cinfo->clientaddr).sin_addr), buf, cinfo->clientlen),
85             ntohs(cinfo->clientaddr.sin_port),
86             ctime(&now));
87 
88     write(cinfo->clientfd, buffer, strlen(buffer));
89 
90     close(cinfo->clientfd);
91 
92     free(cinfo);
93     
94     return NULL;
95 }

 

 

posted on 2013-04-15 19:10  Zirconi  阅读(289)  评论(0编辑  收藏  举报