不同的服务器测试使用了相同的客户端代码,服务器实现的功能是简单的将客户端发过来的数据发回客户端。
客户端代码如下:
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <strings.h> int main(int argc, char **argv) { if(3 != argc) { printf("Usage: %s <IP> <PORT>\n", argv[0]); exit(-1); } int my_fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == my_fd) { perror("socket"); exit(-1); } struct sockaddr_in serveraddr = {0}; serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(atoi(argv[2])); serveraddr.sin_addr.s_addr = inet_addr(argv[1]); if(-1 == connect(my_fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) { perror("connect"); exit(-1); } printf("success !\n"); char buf[100]; while(1) { printf("input: ");fflush(stdout); gets(buf); write(my_fd, buf, 100); bzero(buf, 100); read(my_fd, buf, 100); printf("recv : %s\n", buf); } }
1.进程实现并发服务器设计
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <time.h> #include <string.h> int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == listen_fd) { perror("socket"); exit(-1); } struct sockaddr_in myaddr = {0}, clientaddr= {0}; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(8888); myaddr.sin_addr.s_addr = inet_addr("0.0.0.0");//0 //INADDR_ANY if(-1 == bind(listen_fd, (struct sockaddr*)&myaddr, sizeof(myaddr))) { perror("bind"); exit(-1); } listen(listen_fd, 10); int len = sizeof(clientaddr);//应指定大小 char buf[100]; while(1) { int client_fd = accept(listen_fd, (struct sockaddr*)&clientaddr, &len); if(-1 == client_fd) { perror("accept"); exit(-1); } printf("incomming: %s\n", inet_ntoa(clientaddr.sin_addr) ); pid_t pid = fork(); if(0 == pid) { printf("creat process: %d\n", getpid()); close(listen_fd); while(1) { read(client_fd, buf, 100); if(0 == strncmp("time", buf, 4)) { time_t t = time(NULL); snprintf(buf, 20, "%s", ctime(&t)); // strcpy(buf, ctime(&t)); } if(0 == strncmp("quit", buf, 4)) { close(client_fd); exit(0); } write(client_fd, buf, 100); } } } }
2.多线程实现并发服务器
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <time.h> #include <string.h> #include <pthread.h> void *fun(void *p) { int client_fd = *((int*)p);//???? char buf[100]; while(1) { read(client_fd, buf, 100); if(0 == strncmp("time", buf, 4)) { time_t t = time(NULL); snprintf(buf, 20, "%s", ctime(&t)); // strcpy(buf, ctime(&t)); } write(client_fd, buf, 100); } } int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == listen_fd) { perror("socket"); exit(-1); } struct sockaddr_in myaddr = {0}, clientaddr= {0}; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(8888); myaddr.sin_addr.s_addr = inet_addr("0.0.0.0");//0 //INADDR_ANY if(-1 == bind(listen_fd, (struct sockaddr*)&myaddr, sizeof(myaddr))) { perror("bind"); exit(-1); } listen(listen_fd, 10); int len = sizeof(clientaddr);//应指定大小 char buf[100]; while(1) { int client_fd = accept(listen_fd, (struct sockaddr*)&clientaddr, &len); if(-1 == client_fd) { perror("accept"); exit(-1); } printf("incomming: %s\n", inet_ntoa(clientaddr.sin_addr) ); pthread_t t; pthread_create(&t, NULL, fun, &client_fd); printf("create thread: %ld\n", t); } }
3.多路IO复用实现的并发服务器
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <time.h> #include <string.h> int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == listen_fd) { perror("socket"); exit(-1); } struct sockaddr_in myaddr = {0}, clientaddr= {0}; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(8888); myaddr.sin_addr.s_addr = inet_addr("0.0.0.0");//0 //INADDR_ANY if(-1 == bind(listen_fd, (struct sockaddr*)&myaddr, sizeof(myaddr))) { perror("bind"); exit(-1); } listen(listen_fd, 10); fd_set readfds; FD_ZERO(&readfds); FD_SET(listen_fd, &readfds); fd_set tem_fds = readfds; int max_fd = listen_fd; while(1) { readfds = tem_fds; if(-1 == select(max_fd+1, &readfds, NULL, NULL, NULL)) { perror("select"); exit(-1); } if(FD_ISSET(listen_fd, &readfds)) { int len = sizeof(clientaddr);//应指定大小 int client_fd = accept(listen_fd, (struct sockaddr*)&clientaddr, &len); if(-1 == client_fd) { perror("accept"); exit(-1); } printf("incomming: %s\n", inet_ntoa(clientaddr.sin_addr) ); FD_SET(client_fd, &tem_fds); max_fd = (max_fd > client_fd) ? max_fd:client_fd; } int i; for(i = 0; i<max_fd+1; i++) { if(FD_ISSET(i, &readfds) && i!=listen_fd) { char buf[100]; read(i, buf, 100); if(0 == strncmp("time", buf, 4)) { time_t t = time(NULL); snprintf(buf, 20, "%s", ctime(&t)); // strcpy(buf, ctime(&t)); } write(i, buf, 100); }//if } }//while }
4.循环服务器
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <time.h> #include <string.h> int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == listen_fd) { perror("socket"); exit(-1); } struct sockaddr_in myaddr = {0}, clientaddr= {0}; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(8888); myaddr.sin_addr.s_addr = inet_addr("0.0.0.0");//0 //INADDR_ANY if(-1 == bind(listen_fd, (struct sockaddr*)&myaddr, sizeof(myaddr))) { perror("bind"); exit(-1); } listen(listen_fd, 10); int len = sizeof(clientaddr);//应指定大小 char buf[100]; while(1) { int client_fd = accept(listen_fd, (struct sockaddr*)&clientaddr, &len); if(-1 == client_fd) { perror("accept"); exit(-1); } printf("incomming: %s\n", inet_ntoa(clientaddr.sin_addr) ); while(1) { read(client_fd, buf, 100); if(0 == strncmp("time", buf, 4)) { time_t t = time(NULL); snprintf(buf, 20, "%s", ctime(&t)); // strcpy(buf, ctime(&t)); } if(0 == strncmp("quit", buf, 4)) break; write(client_fd, buf, 100); } } }