🔥博客主页: 我要成为C++领域大神
🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】
❤️感谢大家点赞👍收藏⭐评论✍️本博客致力于知识分享,与更多的人进行学习交流
单进程服务器
处理流程:
1、客户端发送请求
2、服务端处理请求
3、服务端发送响应
4、客户端接收响应
使用单进程服务器测试业务:
客户端向标准输入发送小写字符串,服务端响应回复对应大写字符,"abcAS"->"ABCAS"
客户端向服务端发送关键字localtime,服务端响应回复系统时间、
服务端:
#include <stdio.h>#include <stdlib.h>#include <arpa/inet.h>#include <sys/socket.h>#include <string.h>#include <time.h>#define _SERVER_IP "xxx.xxx.xxx.xxx"//这里修改为你服务器的IP地址#define _PORT 8080#define _BACKLOG 128#define _SHUTDOWN 1#define _TRUE 1#define _FALSE 0#define _IPSIZE 16#define _RECVLEN 1500int main(){ int recvlen; struct sockaddr_in serverAddr,clientAddr; int server_fd; int client_fd; char Result[_RECVLEN]; char client_ip[_IPSIZE]; socklen_t Addrlen; serverAddr.sin_family=AF_INET; serverAddr.sin_port=htons(_PORT); serverAddr.sin_addr.s_addr=htonl(INADDR_ANY); server_fd=socket(AF_INET,SOCK_STREAM,0); bind(server_fd,(struct sockaddr*)&serverAddr,sizeof(serverAddr)); listen(server_fd,_BACKLOG); printf("Test TCP Server Version 1.1.0 is Running.../n"); time_t tp; char time_buf[100];//存放当前系统时间 int toupper_flag; while(_SHUTDOWN) { Addrlen=sizeof(clientAddr); if((client_fd=accept(server_fd,(struct sockaddr*)&clientAddr,&Addrlen))>0) { //Socket通信 bzero(Result,sizeof(Result)); bzero(client_ip,sizeof(client_ip)); inet_ntop(AF_INET,&clientAddr.sin_addr.s_addr,client_ip,_IPSIZE); printf("Connection From :IP[%s],PORT[%d]/n",client_ip,ntohs(clientAddr.sin_port)); sprintf(Result,"Hi [%s] Welcome to my TCP test server!service version 1.1.0...",client_ip); send(client_fd,Result,strlen(Result),0); //读取用户数据1,如果用户发的是普通小写字符字符串,转换为大写,如果发送的是local关键字,响应时间 bzero(Result,sizeof(Result)); //持续响应,循环读写 while((recvlen=recv(client_fd,Result,sizeof(Result),0))>0) { printf("Client Say:%s/n",Result); if(strcmp(Result,"localtime")==0) { tp=time(NULL);//获取时间种子 ctime_r(&tp,time_buf); time_buf[strcspn(time_buf,"/n")]='/0'; printf("[%s]Response SysTime Successfully!/n",client_ip); send(client_fd,time_buf,strlen(time_buf)+1,0); } else { toupper_flag=0; while(recvlen>toupper_flag) { Result[toupper_flag]=toupper(Result[toupper_flag]); ++toupper_flag; } printf("[%s]Response Toupper Successfully!/n",client_ip); send(client_fd,Result,recvlen,0); } } close(client_fd); } else { perror("accpet failed"); close(server_fd); exit(0); } } close(server_fd); return 0;}
客户端:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/socket.h>#include <arpa/inet.h>//客户端源码编写,连接服务器成功,服务器反馈信息#define _IP "xxx.xxx.xxx.xxx"//这里修改为你服务器的IP地址#define _PORT 8080int main(){ struct sockaddr_in ServerAddr; bzero(&ServerAddr,sizeof(ServerAddr)); ServerAddr.sin_family=AF_INET; ServerAddr.sin_port=htons(_PORT); inet_pton(AF_INET,_IP,&ServerAddr.sin_addr.s_addr); int Myfd=socket(AF_INET,SOCK_STREAM,0); //看需求决定是否要绑定 char Response[1024];//存放服务端反馈信息 ssize_t recvlen; bzero(Response,sizeof(Response)); if((connect(Myfd,(struct sockaddr *)&ServerAddr,sizeof(ServerAddr)))==0) { if((recvlen=recv(Myfd,Response,sizeof(Response),0))>0) { printf("%s/n",Response); } } else { printf("Connect failed/n"); close(Myfd); exit(0); } close(Myfd); printf("Client is Over/n"); return 0;}
完成了大小写转换,系统时间的响应:
当再打开一个终端:因为只有一个进程响应客户端,所以新的客户端进程被阻塞了。只有上一个进程退出,新的客户端进程才能连接
缺点:一次只能处理一个客户端