socket 实现简单的计算器

     socket 实现简单的的计算器

  服务端  server.c  对客户端的请求进行处理,并返回结果

   客户端  client.c  向服务端发送一个表达式 如 add 1  2 表示 1+2 服务器返回结果;

   主要功能 +  - *  / echo

   代码:server.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/un.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<netdb.h>
#include<signal.h>
#include<ctype.h>


#define PORT  5000
//获取子进程退出信号 在退出时给出提示信息
void sig_handler(int signo)
{
		pid_t pid;
		int stat;
		pid = waitpid(-1,&stat,WNOHANG);
	 while(pid>0){
		 printf("child process terminated (PID: %ld)\n",(long)getpid());	
		 pid = waitpid(-1,&stat,WNOHANG);
	 }
return;
}
typedef struct{
		double a;
		double b;
		char s[10];
		char echo_buf[1024];
}Mes;


int main(int argc ,char *argv[])
{
		socklen_t clt_addr_len;
		int listen_fd;
		int com_fd;
		int i;
		static char send_buf[1024];
		int len;
		int port;
		pid_t pid;


		struct sockaddr_in clt_addr;
		struct sockaddr_in srv_addr;
		if(argc!=1)
		{
				printf("Usage: %s  port\n",argv[0]);
				exit(1);
		}

		if(signal(SIGCHLD,sig_handler) < 0){
				perror("can not set the signal\n");
				exit(1);
		}
		listen_fd = socket(PF_INET,SOCK_STREAM,0);
		if(listen_fd < 0){
				perror("can not create listening socket\n");
				exit(1);
		}
		memset(&srv_addr,0,sizeof(srv_addr));
		srv_addr.sin_family = AF_INET;
	    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);	
		srv_addr.sin_port = htons(PORT);

		int t=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));		 
               if(t==-1){
				perror("can not bind server socket\n");
				exit(1);
		}
		
		t=listen(listen_fd,20);
		if(t==-1){
				perror("can not listen the client connect request\n");
				close(listen_fd);
		}
		memset(send_buf,0,1024);
		while(1)
		{
				len = sizeof(clt_addr);
				com_fd = accept(listen_fd,(struct sockaddr*)&clt_addr,&len);
				if(com_fd < 0){
						if(errno == EINTR){
								continue;
						}
						else{
								perror("can not accept client connect request\n");
								close(listen_fd);
								exit(1);
						}
				}
				pid = fork();
				if(pid < 0){
						perror("can not create the child process\n ");
						close(listen_fd);
						exit(1);
				}else if(pid == 0){
						Mes mes;
						int n=sizeof(mes);


						
						while((len = read(com_fd,&mes,n))>0){


								if(strcmp(mes.s,"echo")!=0){
								printf("Message from client(%d):%s %.2lf %.2lf\n",len,mes.s,mes.a,mes.b);
								if(send_buf[0]=='@'){
										break;
								}
								
								double result =  0;
								if(strcmp(mes.s,"add")==0){
										printf("加法\n");
										result = mes.a+mes.b;
								}else if(strcmp(mes.s,"sub")==0){
										printf("减法\n");
										result = mes.a - mes.b;
								}else if(strcmp(mes.s,"mul")==0){
										printf("乘法\n");
										result = mes.a * mes.b;
								}else if(strcmp(mes.s,"div")==0){
										printf("除法\n");
										if(mes.b == 0){
												printf("除数为0\n ");
												result == 0;
										}else{
												result = mes.a / mes.b;
										}
								}else{
										printf("不识别的操作\n");
								}
								printf("结果:result = %.2lf\n",result);
								if(mes.b == 0 && (strcmp(mes.s,"div") == 0)){
										sprintf(send_buf,"%s","除数为0 无意义\n");
								}else{
								sprintf(send_buf,"%.2lf",result);
								}
							}else{
									printf("客户端的消息:%s\n",mes.echo_buf);
									printf("回复的消息");
									fgets(send_buf,1024,stdin);
							}


								write(com_fd,send_buf,strlen(send_buf));
								
						}
								close(com_fd);
								return 0;
						}else{
								close(com_fd);
						}
		}


			return 0;
}

client.c:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<unistd.h>
#include<netdb.h>
#include<errno.h>
#include<arpa/inet.h>


#define PORT  5000


typedef struct{
		double a;
		double b;
		char s[10];
		char echo_buf[1024];
}Mes;
int main(int argc,char *argv[])
{
		int connect_fd;
		int ret;
		char recv_buf[1024];
		int i;
		int port;
		int len;


		static struct sockaddr_in srv_addr;

		if(argc!=1){
				printf("Usage: %s server_ip_address port \n",argv[0]);
				exit(1);
		}

		connect_fd = socket(PF_INET,SOCK_STREAM,0);
		if(connect_fd < 0){
				perror("can not create communication socket\n");
				exit(1);
		}


		memset(&srv_addr,0,sizeof(srv_addr));
		srv_addr.sin_family = AF_INET;
		srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
		srv_addr.sin_port = htons(PORT);

		if((connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr)))==-1){
				perror("can not to the server\n");
				close(connect_fd);
				exit(1);
		}


		memset(recv_buf,0,1024);


		while(1){
				
				Mes mes;
				int n=sizeof(mes);
				printf("请输入表达式:\n");
				scanf("%s",mes.s);
				if(strcmp(mes.s,"echo")==0){
						fgets(mes.echo_buf,1024,stdin);
						mes.a = 0;
						mes.b = 0;
				}else{
				scanf("%lf%lf",&mes.a,&mes.b);
				sprintf(mes.echo_buf,"%s","NULL");
				}
				write(connect_fd,&mes,n);
				len = read(connect_fd,recv_buf,n);
				if(strcmp(mes.s,"echo")==0){
						printf("服务端回复的消息:%s\n",recv_buf);
				}else if(len > 0){
						double result;
						sscanf(recv_buf,"%lf",&result);
						printf("计算的结果: %.2lf\n",result);
				
				if(recv_buf[0] == '@')
						break;
		}
		}
		close(connect_fd);
		return 0;
}

运行结果截图:

server:



client:



猜你喜欢

转载自blog.csdn.net/fly_sky_share/article/details/78790024