下面是一个简单的时间服务器程序。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <time.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAX_LISTEN 5 #define PORT 1234 int main() { int conn_fd = 0; int sock_fd = 0; int recv_num; int send_num; char recv_buf[100]; char send_buf[100]; int i, ready, max_fd; fd_set readset; int client[FD_SETSIZE]; //用一个数组记录描述符的状态 struct sockaddr_in addr_client; struct sockaddr_in addr_serv; socklen_t client_size; //创建socket sock_fd = socket(AF_INET,SOCK_STREAM,0); if (sock_fd < 0) { printf("create socket failed\n"); return -1; } client_size = sizeof(struct sockaddr_in); //设置套接口 int opt = SO_REUSEADDR; setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); memset(&addr_serv, 0, sizeof(addr_serv)); addr_serv.sin_family = AF_INET; addr_serv.sin_port = htons(PORT); addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); //为创建的socket绑定端口 if (bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(struct sockaddr_in)) < 0) { printf("bind error\n"); return -1; } if (listen(sock_fd, MAX_LISTEN) < 0) { printf("listen error\n"); return -1; } //初始化套接字数组 for (i=0; i<FD_SETSIZE; i++) { client[i] = -1; } max_fd = sock_fd; while (1) { //重置监听的描述符 FD_ZERO(&readset); FD_SET(sock_fd, &readset); for (i=0; i<FD_SETSIZE; i++) { if (client[i] == 1) { FD_SET(i, &readset); } } //开始监听描述符,是异步的,不会阻塞 ready = select(max_fd+1, &readset, NULL, NULL, NULL); //判断是否有可用套接字 if (FD_ISSET(sock_fd, &readset)) { conn_fd = accept(sock_fd, (struct sockaddr *)&addr_client, &client_size); if (conn_fd < 0) { printf("accept error\n"); return -1; } //将新建连接的套接字添加到的select序列 FD_SET(conn_fd, &readset); //从readset序列清除sockfd FD_CLR(sock_fd, &readset); if (conn_fd > max_fd) { max_fd = conn_fd; } client[conn_fd] = 1; } //检查所有的描述符,判断是否有可用套接字,有的话对套接字进行读写操作 for (i=0; i<FD_SETSIZE; i++) { if (FD_ISSET(i, &readset)) { recv_num = recv(i, recv_buf, sizeof(recv_buf), 0); if (recv_num <= 0) { //从readset序列清除i套接字 FD_CLR(i, &readset); client[i] = -1; } recv_buf[recv_num] = '\0'; //获取时间 memset(send_buf, 0, sizeof(send_buf)); struct tm * timeinfo; time_t gttime; time(>time); timeinfo = localtime(>time); char sTime[20]; sprintf(sTime,"%4d-%02d-%02d %02d:%02d:%02d" ,1900+timeinfo->tm_year, 1+timeinfo->tm_mon,timeinfo->tm_mday ,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec); //给客户度端发送时间 send_num = send(i, sTime, strlen(sTime), 0); if (send_num <= 0) { FD_CLR(i, &readset); client[i] = -1; } } } } close(sock_fd); return 0; }