client.c

#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<linux/in.h>
#include<stdlib.h>

//消息数据包
typedef struct msg
{
    int type;//类型
    char name[128];//用户名
    char data[256];//内容
}MSG;
void do_register(int sockfd,MSG *msg);
int do_login(int sockfd,MSG *msg);
void do_query(int sockfd,MSG *msg);    
void do_history(int sockfd,MSG *msg);
int main(int argc, const char *argv[])
{
    if(argc < 3)
    {
        printf("input : %s<ip> <port>\n",argv[0]);
        exit(0);
    }
    MSG msg;
    int login = 0;
    //创建套节字文件
    int sockfd;
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        perror("sockfd err.\n");
        return -1;
    }
    printf("socket yes.\n");
    //填充结构体数组
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

//允许重用本地地址 和端口号     
    int optval = 1;
    socklen_t optval_len = sizeof(optval);
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,optval_len);

socklen_t addrlen = sizeof(serveraddr);
    //连接服务器
    if(connect(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
    {
        perror("connect err.\n");
        return -1;
    }
    printf("connect yes\n");
    char buf[128] = {0};
    int n = 0;
    while(1)
    {   //注册.登录.退出
        printf("*******************************\n");
        printf("* 1:register  2:login  3:quit *\n");
        printf("*******************************\n");
        printf("please choose>>>");
        if(scanf("%d",&n) == 0)
        {
            fgets(buf,sizeof(buf),stdin);
            buf[strlen(buf) -1] = '\0';
            continue;
        }
        switch(n)
        {
        case 1:
            do_register(sockfd,&msg);
            break;
        case 2:
            if(do_login(sockfd,&msg) == 1)
            {
                goto next;
            }
            break;
        case 3:
            close(sockfd);
            exit(0);
        }
    }

void do_register(int sockfd,MSG *msg)
{
    //封装注册msg包
    msg->type = 'R';
    printf("please user name:");
    scanf("%s",msg->name);
    printf("please user code:");
    scanf("%s",msg->data);
    //向服务器发送注册包
    send(sockfd,msg,sizeof(MSG),0);
    //接收服务器反馈
    recv(sockfd,msg,sizeof(MSG),0);
    printf("register: %s\n",msg->data);
    return;
}
int do_login(int sockfd,MSG *msg)
{
    //封装登录包
    msg->type = 'L';
    printf("please user name:");
    scanf("%s",msg->name);
    printf("please user code:");
    scanf("%s",msg->data);
    //发送登录消息
    send(sockfd,msg,sizeof(MSG),0);
    //接收服务器反馈
    recv(sockfd,msg,sizeof(MSG),0);
    //判断是否登录成功
    if(strncmp(msg->data,"OK",3) == 0)
    {
        printf("login OK.\n");
        return 1;
    }
    printf("login:%s\n",msg->data);
    return 0;
}
void do_query(int sockfd,MSG *msg)    
{   //封装查询包
    msg->type = 'Q';
    while(1)
    {
        printf("query word:");
        scanf("%s",msg->data);
        if(strcmp(msg->data,"#") == 0)
            break;
         //发送查询信号
        send(sockfd,msg,sizeof(MSG),0);
         //接收服务器反馈
        recv(sockfd,msg,sizeof(MSG),0);
        //printf优化解释,打印
        printf("%s\n",msg->data);

}
    return ;
}
void do_history(int sockfd,MSG *msg)
{
    //封装历史查询包
    msg->type = 'H';
    send(sockfd,msg,sizeof(MSG),0);
    while(1)
    {
        recv(sockfd,msg,sizeof(MSG),0);
    if(    msg->data[0] == '\0')
        break;
        printf("%s\n",msg->data);
    }
    return;
}

Makefile

all:
    gcc server.c -lsqlite3 -o fwq    
    gcc client.c -o khd

clean:
    rm fwq khd

Sever.c

#include<stdio.h>
#include<sqlite3.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>

//消息数据包
typedef struct 
{
    int type;//类型
    char name[128];//用户名
    char data[256];//内容
}MSG;
int callback(void *arg,int f_num,char **f_value,char **f_name);
void get_date(char *date);
int do_searchword(int acceptfd, MSG *msg);
void do_register(int acceptfd,MSG *msg,sqlite3 *db);
void do_login(int acceptfd,MSG *msg,sqlite3 *db);
void do_query(int acceptfd,MSG *msg,sqlite3 *db);
void do_history(int acceptfd,MSG *msg,sqlite3 *db);
int main(int argc, const char *argv[])
{
    if(argc < 3)
    {
        printf("input :%s,<ip> <port>\n",argv[0]);
        exit(0);
    }
    sqlite3 *db;
    char *errmsg = NULL;
    int sockfd,acceptfd;
    ssize_t recvaddr;
    MSG  msg;
    char buf[128] = {0};
    //创建一个数据库文件
    if(sqlite3_open("str.db",&db) != 0)
    {
        fprintf(stderr,"sqlite3_open failed:%s\n",sqlite3_errmsg(db));
        return -1;
    }
    printf("open yes.\n");
    //添加一个用户信息表,key表明注册的用户名只能唯一
    if(sqlite3_exec(db,"create table str(name char primary key,code char);",NULL,NULL,&errmsg) != 0)
    {
        fprintf(stderr,"create str failed:%s\n",errmsg);
    }
    printf("exec yes.\n");
    //添加一个历史记录的表
    if(sqlite3_exec(db,"create table record(name char,time char,word char);",NULL,NULL,&errmsg) != 0)
    {
        fprintf(stderr,"create record failed:%s\n",errmsg);
    }
    //创建一个套节字文件
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        perror("socket err.\n");
        return -1;
    }
    printf("socket yes.\n");
    //填充结构体数组
    struct sockaddr_in serveraddr,clinentaddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

//允许重用本地地址 和端口号     
    int optval = 1;
    socklen_t optval_len = sizeof(optval);
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,optval_len);

socklen_t serverlen = sizeof(serveraddr);
    socklen_t clinentlen = sizeof(clinentaddr);
    //绑定
    if(bind(sockfd,(struct sockaddr *)&serveraddr,serverlen) < 0)
    {
        perror("bind err.\n");
        return -1;
    }
    printf("bind yes.\n");
    //监听
    if(listen(sockfd,8) < 0)
    {
        perror("listen err.\n");
        return -1;
    }
    printf("listen yes.\n");

//信号处理函数
    signal(SIGCHLD,SIG_IGN);

pid_t pid;
    while(1)
    {   //阻塞等待连接
        if((acceptfd = accept(sockfd,NULL,NULL)) < 0)
        {
            perror("acceptfd err.\n");
            return -1;
        }
        printf("accept yes.\n");
        //创建进程
        if((pid = fork()) < 0)
        {
            perror("fork err.\n");
            return -1;
        }
        else if(pid == 0)
        {
            //循环接收客户端数据存放到msg包里
            while(recvaddr = recv(acceptfd,&msg,sizeof(msg),0) > 0) 
            {
                //根据类型处理
                switch(msg.type)
                {
                case 'R'://.注册
                    do_register(acceptfd,&msg,db);
                    break;
                case 'L'://.登录
                    do_login(acceptfd,&msg,db);
                    break;
                case 'Q'://.查询的单词
                    do_query(acceptfd,&msg,db);
                    break;
                case 'H'://.历史记录
                    do_history(acceptfd,&msg,db);
                    break;
                }
            }
            printf("ip%sclient quit!!!!\n",(char *)inet_ntoa(clinentaddr.sin_addr.s_addr));
            close(acceptfd);
            exit(0);
        }
        else
        {
            printf("** user login. **\n");
        }
    }
    close(sockfd);
    return 0;
}

完整代码请参考:  https://download.csdn.net/download/signal___/18161310?spm=1001.2014.3001.5501

基于linux下的在线电子词典相关推荐

  1. 【基于TCP 在线电子词典】

    基于TCP 在线电子词典 项目功能 流程图 客户端 服务器端 功能实现 服务器 客户端 功能演示 注册功能 登录功能 查询单词功能 查询记录 注销登录(返回上级) 不允许重复登录 Ctrl + C注销 ...

  2. 基于C语言的网络电子词典

    一.概述  本文章是来自于华清远见的一个基于C语言的网络电子词典项目,使用到了tcp协议的并发服务器设计.网络编程.文件I/O.数据库等多方面的知识.可以满足多用户同时登陆,用户登陆后可以查询单词及历 ...

  3. linux环境用opencv读取图片,基于Linux下OpenCV的人脸识别模块设计

    金笑雪 张琳琳 高丹 张黎 摘 要: 近年来,图像识别技术正在向更加直观.可靠的方向发展,其中人脸识别技术具有极高的研究价值,应用得也最为广泛.通过对Linux系统下OpenCV的研究,利用OpenC ...

  4. 基于Linux下 Oracle 备份策略(RMAN)

    基于Linux下 Oracle 备份策略(RMAN) --********************************** -- 基于Linux下 Oracle 备份策略(RMAN) --**** ...

  5. 基于Linux下的即时通讯聊天室项目(全代码 有注释 可直接运行)

    基于Linux下的即时通讯聊天室项目 一.序言 二.具体功能 三.系统客户要求 四.具体代码 1.服务器代码 2.客户端代码 一.序言 最近在写一个基于Linux下的聊天工具 它适合于局域网内所有人进 ...

  6. 基于Linux下 Oracle 备份策略(RMAN)---转自沙弥的世界

    --********************************** -- 基于Linux下 Oracle 备份策略(RMAN) --******************************* ...

  7. 【生物信息学】:基于Linux下的pgap安装及通用教程(持续更新中)

    [PGAP:基于Linux下的安装及通用教程] NCBI软件pgap安装及通用教程 1.需要一个Linux操作系统: 2.基于Linux系统安装docker及pgap 3.pgap测试与使用 -- p ...

  8. linux下的在线围棋程序--CGoban。(转)

    linux下的在线围棋程序--CGoban.(转)[@more@]在网上搞到的,我试过了,能在红旗5.0beta3下使用. 可以下在线游戏.网上还说可以单机对弈,不过我没找到此功能. 第一个附件是rp ...

  9. 基于Linux下的VIM、Mac下的idea实现的协议分析软件

    一.任务概述 1.1 设计目的 使学生深入理解和掌握计算机网络的基本理论及工作原理,熟悉计算机网络和互联网的组成,运用计算机网络知识设计协议分析软件,并进行网络协议分析,最后通过网页呈现,加深对计算机 ...

  10. Linux使用Shell编写电子词典

    使用Shell编写电子词典 代码块 代码块 字典是可以从网上找上传至linux或者直接使用网上词典: #!/bin/bash # #********************************** ...

最新文章

  1. Python 从入门到精通:一个月就够了?真的能行嘛?
  2. IPsec在企业网中的应用
  3. 修改电脑开机时间记录6005_这些优化步骤,让你的电脑远离卡顿!
  4. 两个onCreate方法?你真的了解onCreate()么?
  5. NYOJ1071 - 不可以!
  6. 九度互动社区IT名企招聘上机考试热身赛
  7. 如何使用Java泛型映射不同的值类型
  8. android handler同步,android解决:使用多线程和Handler同步更新UI
  9. 第八节:实战前必须掌握的10个指令(下)
  10. GoogleCode SVN应用(源代码学习)
  11. ios版qq聊天记录的导出
  12. python实现AES加密解密
  13. PL3369C原边12W电源芯片
  14. 图片处理-填充图片-numpy.pad
  15. Android之Fragment回退栈详解
  16. bat脚本--android adb一键截图
  17. Google登录和内购简要说明
  18. ssh登录主机报错: Unable to negotiate with 172.222.222.243 port 22: no matching key exchange method found.
  19. Google需警惕苹果Apple TV的10大原因
  20. kernel 选项详解(stlinux2.3)

热门文章

  1. IE9如何降级返回IE8
  2. win10+ubuntu双系统引导修复
  3. c语言实现61850协议,C语言实现61850库实现代码
  4. 2022年MathorCup建模赛D题:MATLAB代码与若干问题
  5. sql删除重复数据只保留一条的操作方法
  6. asp.net图书馆管理系统
  7. 计算机博弈的代码java,Java 速成
  8. linux查看ipmi端口down,Linux通过命令行设置IPMI的解决方法
  9. IEEE ACCESS模板下载
  10. 怎么快速将Excel文件转为DBF格式文件