socket 实现简单的计算器

来源:互联网 发布:阿里云url中文乱码 编辑:程序博客网 时间:2024/06/09 16:40

     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  5000typedef 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: