/* socket select模型,服务端 绝大多数注释自己写的,参考man */ #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/un.h> #include <sys/time.h> #include <sys/ioctl.h> #include <unistd.h> #include <netinet/in.h> #define SERVPORT 3333 #define BACKLOG 10 #define MAX_CONNECTED_NO 10 #define MAXDATASIZE 100 int main() { /* struct sockaddr_in { //地址族AF_INET(IPv4)AF_INET6(IPv6)AF_LOCAL(UNIX域协议)AF_LINK(链路地址协议)AF_KEY(密钥套接字socket)AF_APPLETALK(ddp) short int sin_family; //端口号 unsigned short int sin_port; * * struct in_addr { * unsigned long s_addr; * } * //地址 struct in_addr sin_addr; unsigned char sin_zero[8]; } eg: struct sockaddr_in ina; bzero(&ina,sizeof(ina)); ina.sin_family=AF_INET; ina.sin_port=htons(23); ina.sin_addr.s_addr = inet_addr("132.241.5.10"); AF_INET和PF_INET略有差异 */ struct sockaddr_in server_sockaddr,client_sockaddr; int sin_size,recvbytes; fd_set readfd; fd_set writefd; int sockfd,client_fd; char buf[MAXDATASIZE]; /* int socket(int domain, int type, int protocol); domain:PF_INET... type:SOCK_STREAM,SOCK_STREAM,SOCK_RAW... protocol:/etc/protocols tcp,udp... */ if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){ perror("socket"); exit(1); } printf("socket success!,sockfd=%d/n",sockfd); server_sockaddr.sin_family=AF_INET; server_sockaddr.sin_port=htons(SERVPORT); server_sockaddr.sin_addr.s_addr=INADDR_ANY; //set to 0 bzero(&(server_sockaddr.sin_zero),8); /* int bind(int sockfd, const struct sockaddr *my_addr,socklen_t addrlen); sockfd:created by socket *my_addr:convert from sockaddr_in addrlen:sizeof(sockaddr) */ if(bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1){ perror("bind"); exit(1); } printf("bind success!/n"); /* int listen(int sockfd, int backlog); sockfd:created by socket backlog:the maximum length the queue of pending connections may grow to(最多接受的connect数) */ if(listen(sockfd,BACKLOG)==-1){ perror("listen"); exit(1); } printf("listening..../n"); /* man FD_ZERO can get FD_ZERO()clears a set. FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set */ FD_ZERO(&readfd); FD_SET(sockfd,&readfd); while(1){ sin_size=sizeof(struct sockaddr_in); /* int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout); nfds:the max file descriptor timeval:struct timeval { time_t tv_sec; // seconds suseconds_t tv_usec; // microseconds } */ if(select(MAX_CONNECTED_NO,&readfd,NULL,NULL,(struct timeval *)0)>0){ if(FD_ISSET(sockfd,&readfd)>0){ /* int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); returns a non-negative integer that is a descriptor for the accepted socket */ if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1){ perror("accept"); exit(1); } /* ssize_t recv(int s, void *buf, size_t len, int flags); flag:most is zero */ if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1){ perror("recv"); exit(1); } if(read(client_fd,buf,MAXDATASIZE)<0){ perror("read"); exit(1); } printf("received a connection :%s",buf); }/*if*/ close(client_fd); }/*select*/ }/*while*/ }