🔥博客主頁:?我要成為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 8080
int 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;
}
完成了大小寫轉換,系統時間的響應:
當再打開一個終端:因為只有一個進程響應客戶端,所以新的客戶端進程被阻塞了。只有上一個進程退出,新的客戶端進程才能連接
缺點:一次只能處理一個客戶端