<Beginning Linux Programming_4th> chapter 15 Sockets
1 A simple local client/server
1) client.c
// 1) header files // int socket(int domain, int type, int protocol); #include <sys/types.h> // int connect(int socket, const struct sockaddr*address,size_t address_len); #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> /* struct sockaddr_in{ short int sin_family; // AF_INET unsigned short int sin_port; // Port number struct in_addr sin_addr; //Internet address }; */ #include <netinet/in.h> #include <arpa/inet.h> // size_t write(int fildes, const void *buf, size_t nbytes); // size_t read(int fildes, const void *buf, size_t nbytes); #include <unistd.h> // 2) socket int main () { // 127.0.0.1 loopback network // 192.168.1.1 local area network via an Ethernet adaptor // 158.152.x.x modem link to an Internet service provider int sockfd; int len; struct sockaddr_in address; int result; char ch = 'A'; /* struct in_addr{ unsigned long int s_addr; }; */ sockfd = socket(AF_INET, SOCK_STREAM, 0); address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr("127.0.0.1"); address.sin_port = htons(9734); len = sizeof(address); /* sizeof(变量/数据类型); // 结果是一个整数 变量或此种数据类型的变量所占的内存空间字节数 printf("the size of char is %d bytes\n", sizeof(char)); */ // 3) connect result = connect(sockfd, (struct sockaddr*) &address, len); if(result == -1) { perror("oops: client"); exit(1); } // 4) write, read and close write(sockfd, &ch, 1); read(sockfd, &ch, 1); printf("char from server = %c\n", ch); close(sockfd); exit(0); } /* convert 16-bit/32-bit integers between host and network ordering <netinet/in.h> unsigned long int htol(unsigned long int hostlong); unsigned short int htos(unsigned short int hostshort); unsigned long int ntohl(unsigned long int netlong); unsigned short int ntohs(unsigned short int netshort);
2) server.c
// 1) header files #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> // 2) socket int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; unlink("server_socket"); server_sockfd = socket(AF_INET, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(9734); server_len = sizeof(server_address); // 3) bind, listen bind(server_sockfd, (struct sockaddr*)&server_address, server_len); listen(server_sockfd, 5); // 4) while loop: accept - read/write - close while(1) { char ch; printf("server waiting\n"); client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len); read(client_sockfd, &ch, 1); ch++; write(client_sockfd, &ch,1); close(client_sockfd); } } // int bind(int socket, const struct sockaddr* address, size_t address_len); // int listen(int socket, int backlog); // int accept(int socket, struct sockaddr* address, size_t* address_len);
2 A server for multiple clients
server2.c
// 1) header files #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <signal.h> #include <unistd.h> // 2) socket int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; server_sockfd = socket(AF_INET, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(9734); server_len = sizeof(server_address); // 3) bind, listen, signal bind(server_sockfd, (struct sockaddr*)&server_address, server_len); listen(server_sockfd, 5); signal(SIGCHLD, SIG_IGN); // 4) while loop: accept - fork while(1) { char ch; printf("server waiting\n"); client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len); if(fork() == 0) { read(client_sockfd, &ch, 1); sleep(5); ch++; write(client_sockfd, &ch,1); close(client_sockfd); exit(0); } else { close(client_sockfd); } } }
3 An improved server for multiple clients
server3.c
// header files #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <sys/time.h> #include <sys/ioctl.h> #include <unistd.h> // 1) socket int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; int result; fd_set readfds, testfds; server_sockfd = socket(AF_INET, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(9734); server_len = sizeof(server_address); // 2) bind, listen bind(server_sockfd, (struct sockaddr*)&server_address, server_len); listen(server_sockfd, 5); FD_ZERO(&readfds); FD_SET(server_sockfd, &readfds); // 3) while loop: server activity, client activity while(1) { char ch; int fd; int nread; testfds = readfds; printf("server waiting\n"); result = select(FD_SETSIZE, &testfds, (fd_set*)0, (fd_set*)0, (struct timeval*)0); if(result<1){ perror("server"); exit(1); } for(fd=0; fd<FD_SETSIZE; fd++) { if(FD_ISSET(fd, &testfds)) { if(fd==server_sockfd) { client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len); FD_SET(client_sockfd, &readfds); printf("adding client an fd %d\n", client_sockfd); } else { ioctl(fd, FIONREAD, &nread); if(nread==0) { close(fd); FD_CLR(fd, &readfds); printf("removing client on fd %d\n", fd); } else { read(fd, &ch, 1); sleep(5); printf("serving client on fd %d\n", fd); ch++; write(fd, &ch, 1); } } // 1st if } // 2nd if } //for } // while } // main
小结:
client: socket -- connect --r/w -- close
server: socket -- bind -- listen -- accept -- r/w -- close
while(1)
server2: socket -- bind -- listen -- signal -- accept -- fork
while(1)
© 著作权归作者所有
相关热门文章
发表评论