循环服务器 tcp
循环服务器工作步骤
1.服务器从请求连接队列中提取连接请求;
2.服务器从客户端接收数据,直到客户端关闭;
3.继续返回第一步;
循环服务器特点
前一个客户端没有结束,下一个服务器就需要一直等待链接,效率不高。
编程实现
客户端
客户端编程方法实现基本连接功能即可,代码如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<signal.h>
int client_fd,server_fd;
void my_func1(int sign_no){
if(sign_no == SIGINT){
// return -1;
send(client_fd,"I break",16,0);
}
}
int main(int argc,char *argv[]){
/* int client_fd,server_fd;*/
server_fd = socket(AF_INET,SOCK_STREAM,0);
if(server_fd == -1){
perror("socket");
return -1;
}
int ret,ret1;
#if 0 //将0改为1执行以下代码
//客户端也可以绑定IP地址
struct sockaddr_in client_addr;
memset(&client_addr,0,sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(9999);
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(ret == -1){
perror("bind");
return -1;
}
#endif
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(9999);
server_addr.sin_addr.s_addr = inet_addr("192.168.47.127");
ret1 = connect(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(ret1 == -1){
perror("connect");
return -1;
}
char buf[16];
memset(buf,0,16);
printf("server_fd %d,server_addr%s,server_port%d\n",server_fd,inet_ntop(AF_INET,&server_addr.sin_addr.s_addr,buf,16),ntohs(server_addr.sin_port));
//signal(SIGINT,my_func1);
while(1){
memset(buf,0,16);
scanf("%s",buf);
do{
ret = write(server_fd,buf,16);
}while(ret == -1 && EINTR == errno);
if(ret == -1){
perror("write");
return -1;
}
if(strncasecmp(buf,"quit",4) == 0){ //如果输入quit之后客户端退出
ret = recv(server_fd,buf,16,0);
if(ret == -1){
perror("recv");
return -1;
}
printf("buf %s\n",buf);
break;
}
// printf("%s\n",buf);
// memset(buf,0,16);
}
close(server_fd);
close(client_fd);
}
服务器
循环服务器主要是体现在服务器端,代码如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<signal.h>
int client_fd,server_fd;
void my_func1(int sign_no){
if(sign_no == SIGINT){
send(client_fd,"I break",16,0);
}
}
int main(int argc,char *argv[]){
server_fd = socket(AF_INET,SOCK_STREAM,0);
if(server_fd == -1){
perror("socket");
return -1;
}
int ret;
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(9999);
int reuse = 1;
setsockopt(server_fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int));
#if 1
server_addr.sin_addr.s_addr = inet_addr("192.168.47.127");
#else
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //可以绑定服务器上的任一地址
#endif
ret = bind(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(ret == -1){
perror("bind");
return -1;
}
ret = listen(server_fd,5);
if(ret == -1){
perror("listen");
return -1;
}
int client_addr_len;
struct sockaddr_in client_addr;
while(1){ //循环服务器的循环部分
memset(&client_addr,0,sizeof(client_addr));
client_addr_len = sizeof(client_addr);
client_fd = accept(server_fd,(struct sockaddr *)&client_addr,&client_addr_len);
if(client_fd == -1){
perror("accept");
return -1;
}
char buf[16];
printf("client_fd %d,client_addr %s,client_port %d\n",client_fd,inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,buf,16),ntohs(client_addr.sin_port));
memset(buf,0,16);
printf("server_fd %d,server_addr %s,server_port %d\n",server_fd,inet_ntop(AF_INET,&server_addr.sin_addr.s_addr,buf,16),ntohs(server_addr.sin_port));
// signal(SIGINT,my_func1);
while(1){
//scanf("%s",buf);
memset(buf,0,16);
do{
ret = read(client_fd,buf,16);
}while(ret == -1 && EINTR == errno);
if(ret == -1){
perror("read");
// return -1;
break;
}
if(strncasecmp(buf,"quit",4) == 0 || ret == 0){
ret = send(client_fd,"you break\n",16,0);
if(ret == -1){
perror("send");
}
break;
}
printf("%s\n",buf);
//memset(buf,0,16);
}
close(client_fd); //客户端执行完毕后关闭套接字
}
}