Linux简单计算服务端和客户端

news/2024/5/18 14:26:31 标签: linux, udp

前几天帮同学写了一个十分简单的基于linux I/O 复用的计算程序,由于应用层协议的设计,只能实现个位数字的四则运算。有需要的可以修改应用层协议。
运行截图:
请添加图片描述
服务端程序代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<string.h>
#include<sys/select.h>
#include<time.h>

#define len 1024

//错误信息输出
void error_hangling(char* message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

//计算函数(可以通过改善该函数实现对计算程序的增强,输入的是单字节字符流)
int calculate(char* messages,int str){
    int str_len =str-1;
    int a[str_len];
    char b[str_len];
    int opnum=0,num=0;
    int result;
    //将数字和运算符分别存储
    for(int i =0 ;i<str_len;++i){
        if(48<=messages[i] && messages[i]<=57){
            a[i] = messages[i]-48;
            num++;
        }
        else{
             b[i] = messages[i];
             ++opnum;
        }

    }


    for(int i=0;i<opnum;++i){
        int false =0;
    //  * 运算符
        for(int j=0;j<str_len;++j){
            if(b[j]=='*' && false == 0){
                false = 1;
                if(i== opnum-1){
                    result=a[j-1]*a[j+1];

                }
                else{
                    int tmp = a[j-1]*a[j+1];
                    a[j-1]=tmp;
                    a[j+1]=tmp;
                    b[j]='#';
                }
                break;
            }

        }
    // /  运算符
         for(int j=0;j<str_len;++j){
            if(b[j]=='/'&& false == 0){
                false = 1;
                if(i== opnum-1){
                    result=a[j-1]/a[j+1];
                }
                else{
                    int tmp = a[j-1]/a[j+1];
                    a[j-1]=tmp;
                    a[j+1]=tmp;
                    b[j]='#';
                }
                break;
            }

        }

    // +  运算符
         for(int j=0;j<str_len;++j){
            if(b[j]=='+'&& false == 0){
                false = 1;
                if(i== opnum-1){
                    result=a[j-1]+a[j+1];
                }
                else{
                    int tmp = a[j-1]+a[j+1];
                    a[j-1]=tmp;
                    a[j+1]=tmp;
                    b[j]='#';
                }
                break;
            }

        }

     // -  运算符
         for(int j=0;j<str_len;++j){
            if(b[j]=='-'&& false == 0){
                false = 1;
                if(i== opnum-1){
                    result=a[j-1]-a[j+1];
                }
                else{
                    int tmp = a[j-1]-a[j+1];
                    a[j-1]=tmp;
                    a[j+1]=tmp;
                    b[j]='#';
                }
                break;
            }

        }

    }


   if(opnum!=0){
        return result;
   }
}

int main(int argc,char *argv[]){
    void error_hangling(char* message);
    int serv_sock,clnt_sock;     
    char message[len];
    int str_len,i;
    int result;

    struct timeval timeout;       //超时结构体
    fd_set reads,cpy_reads;
    int fd_max,fd_num;

    struct sockaddr_in serv_addr,clnt_addr;
    socklen_t clnt_addr_len;

    if(argc!=2){
        printf("<%s>input error\n",argv[0]);
        exit(1);
    }

    serv_sock = socket(PF_INET,SOCK_STREAM,0);

    if(serv_sock==-1){
        error_hangling("socket() error");
    }

    memset(&serv_addr,0,sizeof(serv_addr)); //sock初始化
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    serv_addr.sin_port=htons(atoi(argv[1]));
    
    //绑定
    if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1){
        error_hangling("bind() error");
    }
    
    //监听
    if(listen(serv_sock,5)==-1){
        error_hangling("listen() error");
    }
    
    //文件描述符初始化,
    FD_ZERO(&reads);
    FD_SET(serv_sock,&reads);
    fd_max = serv_sock;

    //监听文件描述符
    while(1){
        cpy_reads = reads;
        timeout.tv_sec = 5;                 //超时时间
        timeout.tv_usec = 5000;

        if((fd_num = select(fd_max+1,&cpy_reads,0,0,&timeout))==-1)
            break;
        if(fd_num==0)
            continue;

        for(i = 0;i<fd_max+1;++i){
            if(FD_ISSET(i,&cpy_reads)){
                if(i == serv_sock){              //connect
                    clnt_addr_len=sizeof(clnt_addr);
                    clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_len);
                    FD_SET(clnt_sock,&reads);
                    if(clnt_sock>fd_max)
                        fd_max=clnt_sock;
                    printf("the connect:%d\n",clnt_sock);

                }

                else{                      //read message
                    str_len = read(i,message,BUFSIZ);
                    if(str_len == 0 ){    //clean
                        FD_CLR(i,&reads);
                        close(i);
                        printf("\nclosed client :%d ",i);
                    }
                    else{
                        result = calculate(message,str_len);
                        write(i,(char *)&result,sizeof(result));
                    }


                }
            }
        }
    }

    close(serv_sock);
    return 0;
}


客户端程序代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<string.h>
#define LEN 100
#define REC_RESULT 4

void error_hangling(char* message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

int main(int argc,char *argv[]){
    int sock;
    char message[LEN];
    int count=0,str_len,recv_result;

    struct sockaddr_in serv_addr;

    if(argc!=3){
        printf("input error\n");
        exit(1);
    }

    sock = socket(PF_INET,SOCK_STREAM,0);
    if(sock==-1){
        error_hangling("socket() error");
    }

    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
    serv_addr.sin_port=htons(atoi(argv[2]));

    if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1){
        error_hangling("connect() error");
    }
    else{
        printf("connect...\n");
    }


    while(1){
        fputs("input message:(q to quit)",stdout);
        fgets(message,LEN,stdin);
        if(!strcmp(message,"q\n"))
            break;

        str_len=write(sock,message,strlen(message));


        read(sock,&recv_result,REC_RESULT);

        printf("\nresult form serve:%d \n",recv_result);

    }
    close(sock);
    return 0;
}



http://www.niftyadmin.cn/n/1663738.html

相关文章

【编译原理学习笔记】3:正规式,正规集,确定的/不确定的有穷自动机

以后*都表示前一个元素的闭包&#xff0c;就当写在了右上角。 正规式和正规集 3型文法(正规文法)所描述的正是终结符集上的正规集&#xff0c;而正规式(正则表达式)就是一种表示正规集的工具。 正规式可以是ε和Φ&#xff0c;对应的正规集是{ε}和{Φ}&#xff0c;还可以是…

CCPD - rpnet 代码复盘

文章目录CCPD - rpnet 网络复盘一、环境准备1、环境版本依赖2、环境搭建2.1、Cuda 部分&#xff1a;2.2、python&#xff1a;CCPD - rpnet 网络复盘 rpnet的代码库&#xff1a;https://github.com/detectRecog/CCPD 一、环境准备 1、环境版本依赖 python: pytorch(0.3.1),…

【Struts2学习笔记】1:认识Struts2和使用方法

从apache上下载Struts2包并解压后&#xff0c;可以看到lib下有很多jar包&#xff0c;按照书上的要求&#xff0c;需要这些&#xff1a; 其中选中的那个是额外下载的&#xff0c;在Struts2的lib里没有。把这些jar包全部放在WEB-INF/lib/下&#xff0c;出现这样的符号就已经导…

数据结构_查找—散列表

数据结构——查找&#xff08;散列表&#xff09;基础概念散列函数的构造方法常用构造方法散列函数的冲突解决方法散列表的查找算法分析基础概念 前面所述的查找过程都是以关键字为基础&#xff0c;对线性表和树表的存储结构进行大类的关键字查找比较。记录中的存储结构的位置…

【编译原理学习笔记】4:从NFA构造等价DFA,对DFA的化简

对NFA的考量是困难的&#xff0c;对DFA的考量则是无比清晰的。对于一个NFA&#xff0c;总存在一个与其等价的DFA。这里"等价"指的是这两个有穷自动机的正规集是相同的。 ε-closure(…)和more(…,…) 在NFA中&#xff0c;ε-closure(A)指的是从状态A经若干ε弧能达…

数据结构——排序(十种常用内排序算法)

排序基础概念和排序方法概述插入排序直接插入排序代码算法分析折半插入排序代码算法分析希尔排序代码算法分析交换排序冒泡排序代码算法分析快速排序代码算法分析选择排序简单选择排序代码算法分析树形选择排序代码算法分析堆排序代码算法分析归并排序2-路归并算法代码算法分析…

pvcreate提示:Device /dev/sdc3 not found (or ignored by filtering)

使用partprobe命令重新读取分区表 [rootjetsen /]# pvcreate /dev/sdc3 Device /dev/sdc3 not found (or ignored by filtering). [rootjetsen /]# dd if/dev/urandom of/dev/sdc3 bs512 count64 640 records in 640 records out 32768 bytes (33 kB) copied, 0.0228513 seco…

【JSP学习笔记】4:使用Model1模式构建购物网站demo

J2EE课的上机题&#xff0c;实现一个Model1模式的购物网站的功能。 编码问题 编码问题终于找到解决方法了&#xff0c;首先保证每个页面能编码的都编成UTF-8&#xff0c;然后所有用到内置对象的地方上来先.setCharacterEncoding("UTF-8");&#xff0c;然后重要的是…