读取键盘输入实例
#include<sys/time.h> #include<sys/types.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<stdio.h> int main() { char buf[10]=""; fd_set rdfds; struct timeval tv; int ret; FD_ZERO(&rdfds); //清空的rdfs文件集合 FD_SET(0,&rdfds); //将标准输入加入到rdfds while(1) { ret = select(1,&rdfds,NULL,NULL,NULL);//阻塞等待用户输入 if(ret<0) printf("selcet failed\n"); else if(ret == 0) printf("seletc timeout\n"); else printf("ret = %d\n",ret); if(FD_ISSET(0,&rdfds)) //测试标准输入是否可读 { printf("reading data\n"); fread(buf,9,0,stdin); //从标准输入中读取数据 } write(1,buf,strlen(buf));//将输入的数据在屏幕显示出来 } return 0; }
web服务器实例
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define MYPORT 88960 // the port users will be connecting to #define BACKLOG 10 // how many pending connections queue will hold #define BUF_SIZE 200 int fd_A[BACKLOG]; // accepted connection fd int conn_amount; // current connection amount int main(void) { int sock_fd, new_fd; //sock_fd监听套接字, new_fd新连接的套接字 struct sockaddr_in server_addr; //服务端地址信息 struct sockaddr_in client_addr; //客户端地址信息 socklen_t sin_size; int yes = 1; char buf[BUF_SIZE]; int ret; int i; if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)//新建监听套接字 { perror("socket error!\n"); exit(1); } if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } server_addr.sin_family = AF_INET; //host byte order server_addr.sin_port = htons(MYPORT); //short, network byte order server_addr.sin_addr.s_addr = INADDR_ANY; //automatically fill with my IP memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero)); if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)//绑定套接字和服务器地址 { perror("bind"); exit(1); } if (listen(sock_fd, BACKLOG) == -1)//侦听监听套接字 { perror("listen"); exit(1); } fd_set fdsr; int maxsock; struct timeval tv; conn_amount = 0; sin_size = sizeof(client_addr); maxsock = sock_fd; while (1) { FD_ZERO(&fdsr);//清空文件描述符集合 FD_SET(sock_fd, &fdsr);//将监听套接字加入到文件描述符集合中 tv.tv_sec = 30;//设置超时时间 tv.tv_usec = 0; for (i = 0; i < BACKLOG; i++) { if (fd_A[i] != 0) { FD_SET(fd_A[i], &fdsr); //将新建的连接套接字加入到文件描述符集合 } } ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);//开始检查文件描述符集合中所有的文件描述符 if (ret < 0) { perror("select" failed!\n); break; } else if (ret == 0) { printf("timeout\n"); continue; } //开始匹配文件描述符集合中所有的文件描述符 for (i = 0; i < conn_amount; i++) { if (FD_ISSET(fd_A[i], &fdsr)) { ret = recv(fd_A[i], buf, sizeof(buf), 0); char str[] = "Good,very nice!\n"; send(fd_A[i],str,sizeof(str) + 1, 0); if (ret <= 0) { // client close printf("client[%d] close\n", i); close(fd_A[i]); FD_CLR(fd_A[i], &fdsr); fd_A[i] = 0; } else { // receive data if (ret < BUF_SIZE) memset(&buf[ret], '\0', 1); printf("client[%d] send:%s\n", i, buf); } } } // 检查是否有新的连接请求 if (FD_ISSET(sock_fd, &fdsr)) { new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); if (new_fd <= 0) { perror("accept"); continue; } //将新的连接套接字加入到fd_A中 if (conn_amount < BACKLOG) { fd_A[conn_amount++] = new_fd; printf("new connection client[%d] %s:%d\n", conn_amount, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); if (new_fd > maxsock) maxsock = new_fd; } else { printf("max connections arrive, exit\n"); send(new_fd, "bye", 4, 0); close(new_fd); break; } } showclient(); } // close other connections for (i = 0; i < BACKLOG; i++) { if (fd_A[i] != 0) { close(fd_A[i]); } } exit(0); }