#i nclude stdio.h
#i nclude stdlib.h
#i nclude errno.h
#i nclude string.h
#i nclude sys/types.h
#i nclude netinet/in.h
#i nclude sys/socket.h
#i nclude sys/wait.h
#define MYPORT 3490 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
main()
{
intsock fd,new_fd; /* 监听socket: sock_fd,数据传输socket:new_fd*/
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in their_addr;/* 客户地址信息 */
int sin_size;
if ((sockfd = socket(AF_INET,SOCK_STREAM, 0)) == -1) { /*错误检测 */
perror("socket");exit(1); }
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr =INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if (bind(sockfd, (structsockaddr *)&my_addr, sizeof(struct sockaddr))
== -1) {/*错误检测*/
perror("bind");exit(1); }
if (listen(sockfd, BACKLOG) ==-1) {/*错误检测*/
perror("listen");exit(1); }
while(1) { /* main accept()loop */
sin_size = sizeof(structsockaddr_in);
if ((new_fd = accept(sockfd,(struct sockaddr *)&their_addr,
&sin_size)) == -1) {
perror("accept");continue; }
printf("server: gotconnection from %s",inet_ntoa(their_addr.sin_addr));
if (!fork()) { /* 子进程代码段 */
if (send(new_fd, "Hello,world!", 14, 0) == -1)
perror("send");close(new_fd); exit(0); }
close(new_fd); /* 父进程不再需要该socket */
waitpid(-1,NULL,WNOHANG) > 0/*等待子进程结束,清除子进程所占用资源*/
}
}
#i ncludestdio.h
#i nclude stdlib.h
#i nclude errno.h
#i nclude string.h
#i nclude netdb.h
#i nclude sys/types.h
#i nclude netinet/in.h
#i nclude sys/socket.h
#define PORT 3490
#define MAXDATASIZE 100 /*每次最大数据传输量 */
int main(int argc, char*argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
if (argc != 2) {
fprintf(stderr,"usage:client hostname"); exit(1); }
if((he=gethostbyname(argv[1]))==NULL){
herror("gethostbyname");exit(1); }
if ((sockfd = socket(AF_INET,SOCK_STREAM, 0)) == -1) {
perror("socket");exit(1); }
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(PORT);
their_addr.sin_addr = *((structin_addr *)he->h_addr);
bzero(&(their_addr.sin_zero),8);
if (connect(sockfd, (structsockaddr *)&their_addr,
sizeof(struct sockaddr)) ==-1) {/*错误检测*/
perror("connect");exit(1); }
if ((numbytes=recv(sockfd, buf,MAXDATASIZE, 0)) == -1) {
perror("recv");exit(1); }
buf[numbytes] = '';
printf("Received:%s",buf);
close(sockfd);
return 0;
}
FD_ZERO(fd_set *set)----清除一个文件描述符集;
FD_SET(int fd,fd_set *set)----将一个文件描述符加入文件描述符集中;
FD_CLR(int fd,fd_set *set)----将一个文件描述符从文件描述符集中清除
;
FD_ISSET(int fd,fd_set*set)----试判断是否文件描述符被置位。
Timeout参数是一个指向struct timeval类型的指针,它可以使select()在等待timeout长时间后没有文件描述符准备好即返回。struct timeval数据结构为:
struct timeval {
int tv_sec; /* seconds */
int tv_usec; /* microseconds*/
};
我们通过程序3来说明:
#i nclude sys/time.h
#i nclude sys/types.h
#i nclude unistd.h
#define STDIN 0 /*标准输入文件描述符*/
main()
{
struct timeval tv;
fd_set readfds;
tv.tv_sec = 2;
tv.tv_usec = 500000;
FD_ZERO(&readfds);
FD_SET(STDIN,&readfds);
/* 这里不关心写文件和异常处理文件描述符集合 */
select(STDIN+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds)) printf("Akey was pressed!");
else printf("Timedout.");
}
(程序3)
select()在被监视端口等待2.5秒钟以后,就从select返回