• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

TCP协议和sqlite3数据库的网络电子词典个人项目

武飞扬头像
恣行
帮助1

一、开发环境:Ubuntu 16.04

二、项目描述

基于TCP协议的并发服务器设计,采用sql数据库进行数据存储,文件保存历史查询数据,能满足多用户同时登陆,实现用户的注册、登录以及退出,登录成功后即可使用单词查询和查询历史记录功能。

三、代码实现思路:

  1. 使用sqlite3数据库,创建用户信息表和单词表。
  2. 服务器采用基于TCP协议的多进程技术,可以满足多用户同时登录。
  3. 服务器接收客户端的注册请求,将用户名和密码存入数据库的注册表中。
  4. 服务器接收客户端的登录请求,将登录信息与注册表中的信息进行比对,反馈对比信息。
  5. 客户端登录成功后,开启查询单词和历史记录功能。
  6. 服务器接收客户端的查询单词后,对比数据库中的单词表,反馈给客户端相应的信息。并用文件IO接收从服务器发来的单词及其释义。
  7. 若客服端发送查询历史记录请求后,打开历史记录文件描述符,打印出该用户查询过的所有历史记录。

四、运用技术点:

  1. 采用文件IO对历史数据进行读写操作。
  2. 采用TCP协议的并发服务器设计。
  3. SQLite3数据库。

五、背景

   任何一种词语,使用频率高了,就会成为公共词汇。英语作为一种国际通用

性语言,部分单词已成为公共词汇,并且直接应用到汉语中来。因其表达简洁,

准确而受到人们青睐。但是,这些新引入或者比较专业词汇,对于较少关注新闻,

接触网络的群体而言,就会造成阅读困难。传统的纸质英汉词典因为更新周期久,

携带不便,价格相对昂贵而不能广泛应用。方便,高效,快捷的电子词典才能满

足现代人的需要。

参考资料

名称

作者

出版社

Unix网络编程

   

TCP/IP协议详解

   

Unix高级环境编程

   

六、系统概述

我们的这套系统采用的是tcp协议的并发服务器设计,可以满足多用户同时登录,用户登录后可以查询单词及历史记录,对于数据的存储我们采用的是sql数据库技术,查找快速,保密性好!

>具体功能能如下:

<1>主界面

  (1)  用户登录

  (2)  用户注册

  (3)  用户退出

学新通

<2>登陆成功后界面

 (1)  查询单词

 (2)  查询历史记录

 (3)  用户退出

学新通

<3>详细设计

消息类型设计

宏名设计

说明

USER_REGISTER

用户注册

USER_LOGIN

用户登陆

USER_WORD

用户查询单词

USER_SUCCESS

登陆成功

USER_FALIURE

登陆失败

4.2结构体的设计

注:__attribute__((__packed__))表示取消结构体对齐

typedef struct

{

char _username[25];  //用户名

char _password[25];     //密码

} __attribute__((__packed__))user_t;   

typedef struct

{

int  type;

int  size;

union

{

user_t  uinfo;    //用户信息

char    _word[100];

} content;

//客户端填词,服务端填写单词解释

#define word    content._word

#define username content.uinfo._username

#define password       content.uinfo._passwd

}__attribute__((__packed__))mhead_t;

#define EXEC_SQL(db,sql,errmsg) do{\

if(sqlite3_exec(db,sql,NULL,NULL,&merrmsg) < 0)\

{\

fprintf(stderr,“sqlite exec [%s]error : %s\n”,sql,errmsg);\

exit(EXIT_FAILURE);

}\

}while(0);

七、服务器

  1.  
    #include "head.h"
  2.  
     
  3.  
    int do_register(int sockfd,sqlite3 *pdb,char *_username,char *_password)
  4.  
    {
  5.  
    char *errmsg;
  6.  
    char buf[1024];
  7.  
    char **dbresult;
  8.  
    int nrow = 0,ncolumn = 0;
  9.  
    char sql[1024] = {0};
  10.  
    mhead_t *head = (mhead_t *)buf;
  11.  
     
  12.  
    sprintf(sql,"select * from user_table where NAME='%s';",_username);
  13.  
    if(sqlite3_get_table(pdb,sql,&dbresult,&nrow,&ncolumn,&errmsg) != 0)
  14.  
    {
  15.  
    fprintf(stderr,"sqlite3 get table error : %s.\n",errmsg);
  16.  
    exit(EXIT_FAILURE);
  17.  
    }
  18.  
     
  19.  
    //没有这样的用户名
  20.  
    if(nrow == 0)
  21.  
    {
  22.  
    //录入数据库
  23.  
    bzero(sql,sizeof(sql));
  24.  
    sprintf(sql,"insert into user_table values('%s','%s');",_username,_password);
  25.  
    EXEC_SQL(pdb,sql,errmsg);
  26.  
     
  27.  
    printf("ok ........\n");
  28.  
     
  29.  
    head->type = USER_SUCCESS;
  30.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  31.  
    {
  32.  
    perror("Fail to send");
  33.  
    exit(EXIT_FAILURE);
  34.  
    }
  35.  
    //注册失败,用户名存在
  36.  
    }else{
  37.  
    head->type = USER_FAILURE;
  38.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  39.  
    {
  40.  
    perror("Fail to send");
  41.  
    exit(EXIT_FAILURE);
  42.  
    }
  43.  
    //表示未知
  44.  
    printf("???????\n");
  45.  
    }
  46.  
    //插入到数据库之后,释放dbresult结果
  47.  
    sqlite3_free_table(dbresult);
  48.  
    return 0;
  49.  
    }
  50.  
     
  51.  
    int do_login(int sockfd,sqlite3 *pdb,char *_username,char *_password)
  52.  
    {
  53.  
    int i,j,index = 0,ret;
  54.  
    char *errmsg;
  55.  
    char buf[1024];
  56.  
    char **dbresult;
  57.  
    int nrow = 0,ncolumn = 0;
  58.  
    char sql[1024] = {0};
  59.  
    mhead_t *head = (mhead_t *)buf;
  60.  
     
  61.  
    sprintf(sql,"select * from user_table where NAME='%s';",_username);
  62.  
    if(sqlite3_get_table(pdb,sql,&dbresult,&nrow,&ncolumn,&errmsg) != 0)
  63.  
    {
  64.  
    fprintf(stderr,"sqlite3 get table error : %s.\n",errmsg);
  65.  
    exit(EXIT_FAILURE);
  66.  
    }
  67.  
     
  68.  
    //有这样的用户名
  69.  
    if(nrow > 0)
  70.  
    {
  71.  
    bzero(sql,sizeof(sql));
  72.  
    EXEC_SQL(pdb,sql,errmsg);
  73.  
    printf("ok........\n");
  74.  
    for(i = 0;i <= nrow;i )
  75.  
    {
  76.  
    for(j = 0;j < ncolumn;j )
  77.  
    {
  78.  
    if(strcmp(dbresult[index],_password) == 0)
  79.  
    {
  80.  
    head->type = USER_SUCCESS;
  81.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  82.  
    {
  83.  
    perror("Fail to send");
  84.  
    exit(EXIT_FAILURE);
  85.  
    }
  86.  
    i = nrow 1;
  87.  
    break;
  88.  
    }
  89.  
    index ;
  90.  
    }
  91.  
    }
  92.  
    }else if(nrow == 0)
  93.  
    {
  94.  
    head->type = USER_FAILURE;
  95.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  96.  
    {
  97.  
    perror("Fail to send");
  98.  
    exit(EXIT_FAILURE);
  99.  
    }
  100.  
    //表示未知
  101.  
    printf("???????\n");
  102.  
    }
  103.  
     
  104.  
    //插入到数据库之后,释放dbresult结果
  105.  
    sqlite3_free_table(dbresult);
  106.  
    return 0;
  107.  
    }
  108.  
     
  109.  
    //获取系统时间
  110.  
    int get_data()
  111.  
    {
  112.  
    time_t t;
  113.  
    time(&t);//获得从1970年1月1日开始到现在有多少秒
  114.  
    printf("current time:%s\n",ctime(&t));//获得当前的时间
  115.  
    return 0;
  116.  
    }
  117.  
     
  118.  
    int do_query(int sockfd,sqlite3 *pdb,char *_word)
  119.  
    {
  120.  
    int ret;
  121.  
    char *errmsg;
  122.  
    char buf[1024] = {0};
  123.  
    char **dbresult;
  124.  
    char sql[1024] = {0};
  125.  
    int nrow = 0,ncolumn = 0;
  126.  
    mhead_t *head = (mhead_t *)buf;
  127.  
    int i = 0,j = 0,index = 0;
  128.  
     
  129.  
    sprintf(sql,"select * from dict_table where word = '%s';",_word);
  130.  
    printf("%s\n",_word);
  131.  
     
  132.  
    if(sqlite3_get_table(pdb,sql,&dbresult,&nrow,&ncolumn,&errmsg) != 0)
  133.  
    {
  134.  
    fprintf(stderr,"sqlite3 get table error : %s.\n",errmsg);
  135.  
    exit(EXIT_FAILURE);
  136.  
    }
  137.  
    if(nrow > 0)
  138.  
    {
  139.  
    printf("ok........\n");
  140.  
    for(i = 0;i <= nrow;i )
  141.  
    {
  142.  
    for(j = 0;j < ncolumn;j )
  143.  
    {
  144.  
    if(strcmp(dbresult[index],_word) == 0)
  145.  
    {
  146.  
    puts(dbresult[index 1]);
  147.  
    sprintf(head->word,"%s:%s\n",_word,dbresult[index 1]);
  148.  
    i=nrow 1;
  149.  
    break;
  150.  
    }
  151.  
    index ;
  152.  
    }
  153.  
    }
  154.  
    head->type = USER_SUCCESS;
  155.  
    printf("%s\n",head->word);
  156.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  157.  
    {
  158.  
    perror("Fail to send");
  159.  
    exit(EXIT_FAILURE);
  160.  
    }
  161.  
     
  162.  
    }
  163.  
    else if(nrow == 0)
  164.  
    {
  165.  
    head->type = USER_FAILURE;
  166.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  167.  
    {
  168.  
    perror("Fail to send");
  169.  
    exit(EXIT_FAILURE);
  170.  
    }
  171.  
    else
  172.  
    //表示未知
  173.  
    printf("???????\n");
  174.  
    }
  175.  
    sqlite3_free_table(dbresult);
  176.  
    return 0;
  177.  
    }
  178.  
     
  179.  
    int do_client(int sockfd,sqlite3 *pdb)
  180.  
    {
  181.  
    int n;
  182.  
    int count = 0;
  183.  
    char buf[1024];
  184.  
    mhead_t *head = (mhead_t *)buf;
  185.  
     
  186.  
    while(1)
  187.  
    {
  188.  
    count = 0;
  189.  
    //接收协议头
  190.  
    while(1)
  191.  
    {
  192.  
    n = recv(sockfd,buf count,sizeof(mhead_t) - count,0);
  193.  
    if(n <= 0){
  194.  
    exit(EXIT_FAILURE);
  195.  
    }
  196.  
    count = n;
  197.  
    printf("count : %d mhead_t : %d\n",count,sizeof(mhead_t));
  198.  
    if(count == sizeof(mhead_t))
  199.  
    break;
  200.  
    }
  201.  
     
  202.  
    switch(head->type)
  203.  
    {
  204.  
    case USER_REGISTER:
  205.  
    do_register(sockfd,pdb,head->username,head->password);
  206.  
    break;
  207.  
    case USER_LOGIN:
  208.  
    do_login(sockfd,pdb,head->username,head->password);
  209.  
    break;
  210.  
    case USER_WORD:
  211.  
    do_query(sockfd,pdb,head->word);
  212.  
    break;
  213.  
    defalut:
  214.  
    exit(EXIT_SUCCESS);
  215.  
    }
  216.  
    }
  217.  
     
  218.  
    return 0;
  219.  
    }
学新通

八、客户端

  1.  
    #include "head.h"
  2.  
    //用户提示界面1
  3.  
    void help_info1()
  4.  
    {
  5.  
    printf("\t-----------------------------------------------\n");
  6.  
    printf("\t| 在线辞典 |\n");
  7.  
    printf("\t|版本:0.0.1 |\n");
  8.  
    printf("\t|作者:XXX |\n");
  9.  
    printf("\t|功能: |\n");
  10.  
    printf("\t| [1] 登录 |\n");
  11.  
    printf("\t| [2] 注册 |\n");
  12.  
    printf("\t| [3] 退出 |\n");
  13.  
    printf("\t|注意:用户只有登录成功后才能进入查单词界面 |\n");
  14.  
    printf("\t------------------------------------------------\n");
  15.  
    return;
  16.  
    }
  17.  
    void help_info2()
  18.  
    {
  19.  
    printf("\t-----------------------------------------------\n");
  20.  
    printf("\t| 欢迎进入查询界面 |\n");
  21.  
    printf("\t|版本:0.0.1 |\n");
  22.  
    printf("\t|作者:XXX |\n");
  23.  
    printf("\t|功能: |\n");
  24.  
    printf("\t| [1] 查询单词 |\n");
  25.  
    printf("\t| [2] 查询历史 |\n");
  26.  
    printf("\t| [3] 退出 |\n");
  27.  
    printf("\t------------------------------------------------\n");
  28.  
    return;
  29.  
    }
  30.  
     
  31.  
     
  32.  
    //用户输入指令,供大家选择
  33.  
    enum{
  34.  
    LOGIN = 1, //登陆
  35.  
    REGISTER = 2, //注册
  36.  
    QUIT = 3, //退出
  37.  
    QUERY = 1, //查询单词
  38.  
    HISTORY = 2, //查询历史
  39.  
    };
  40.  
     
  41.  
    int init_tcp(char *ip,char *port)
  42.  
    {
  43.  
    int sockfd;
  44.  
    struct sockaddr_in server_addr;
  45.  
     
  46.  
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  47.  
    {
  48.  
    perror("Fail to socket");
  49.  
    exit(EXIT_FAILURE);
  50.  
    }
  51.  
     
  52.  
    bzero(&server_addr,sizeof(server_addr));
  53.  
    server_addr.sin_family = AF_INET;
  54.  
    server_addr.sin_port = htons(atoi(port));
  55.  
    server_addr.sin_addr.s_addr = inet_addr(ip);
  56.  
     
  57.  
    if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
  58.  
    {
  59.  
    perror("Fail to bind");
  60.  
    exit(EXIT_FAILURE);
  61.  
    }
  62.  
     
  63.  
    return sockfd;
  64.  
    }
  65.  
     
  66.  
    int do_register(int sockfd)
  67.  
    {
  68.  
    int n = 0;
  69.  
    int count = 0;
  70.  
    char buf[1024] = {0};
  71.  
    //定义发送的协议头
  72.  
    mhead_t *head = (mhead_t *)buf;
  73.  
     
  74.  
    printf("\n您正在注册,请输入用户名和密码\n");
  75.  
     
  76.  
    head->type = USER_REGISTER;
  77.  
    head->size = sizeof(mhead_t);
  78.  
     
  79.  
    printf("Input username : ");
  80.  
    fgets(head->username,sizeof(head->username),stdin);
  81.  
    head->username[strlen(head->username) - 1] = '\0';
  82.  
     
  83.  
    printf("Input password : ");
  84.  
    fgets(head->password,sizeof(head->password),stdin);
  85.  
    head->password[strlen(head->password) - 1] = '\0';
  86.  
     
  87.  
    //发给服务器端
  88.  
     
  89.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  90.  
    {
  91.  
    perror("Fail to send");
  92.  
    exit(EXIT_FAILURE);
  93.  
    }
  94.  
     
  95.  
    bzero(&buf,sizeof(buf));
  96.  
    while(1)
  97.  
    {
  98.  
    //接收数据,TCP是可靠的连接,若是数据
  99.  
    //未完全接收的话,可以在接收
  100.  
    n = recv(sockfd,buf count,sizeof(mhead_t) - count,0);
  101.  
     
  102.  
    if(n <= 0){
  103.  
    perror("Fail to send");
  104.  
    exit(EXIT_FAILURE);
  105.  
    }
  106.  
    //若是数据未发送完成,再次接收的时候可补充
  107.  
    count = n;
  108.  
    if(count == sizeof(mhead_t))
  109.  
    break;
  110.  
    }
  111.  
     
  112.  
    if(head->type == USER_SUCCESS)
  113.  
    {
  114.  
    printf("\n恭喜您,注册成功!\n");
  115.  
    return 0;
  116.  
    }else{ sprintf(buf,"%s\n",head->word);
  117.  
    write(fd,buf,strlen(buf));
  118.  
     
  119.  
    printf("\n很遗憾,这个用户名已经被其它用户注册过了,请重新注册");
  120.  
    return -1;
  121.  
    }
  122.  
    }
  123.  
     
  124.  
    int do_query(int sockfd)
  125.  
    {
  126.  
    time_t t;
  127.  
    time(&t);//获得从1970年1月1日开始到现在有多少秒
  128.  
     
  129.  
    int fd;
  130.  
    int n = 0,count = 0;
  131.  
    char buf[1024] = {0};
  132.  
    char time[1024] = {0};
  133.  
    mhead_t *head = (mhead_t *)buf;
  134.  
    head->type = USER_WORD;
  135.  
    head->size = sizeof(mhead_t);
  136.  
     
  137.  
    fd = open("history.txt",O_RDWR | O_CREAT | O_APPEND,0666);
  138.  
    printf("\n您正在查询单词!\n");
  139.  
    printf("请输入你想要查询的单词:");
  140.  
    fgets(head->word,sizeof(head->word),stdin);
  141.  
    head->word[strlen(head->word) - 1] = '\0';
  142.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  143.  
    {
  144.  
    perror("Fail to send");
  145.  
    exit(EXIT_FAILURE);
  146.  
    }
  147.  
    bzero(&buf,sizeof(buf));
  148.  
    while(1)
  149.  
    {
  150.  
    //接收数据,TCP是可靠的连接,若是数据
  151.  
    //未完全接收的话,可以在接收
  152.  
    n = recv(sockfd,buf count,sizeof(mhead_t) - count,0);
  153.  
    if(n <= 0){
  154.  
    perror("Fail to send");
  155.  
    exit(EXIT_FAILURE);
  156.  
    }
  157.  
    //若是数据未发送完成,再次接收的时候可补充
  158.  
    count = n;
  159.  
    if(count == sizeof(mhead_t))
  160.  
    break;
  161.  
    }
  162.  
     
  163.  
    if(head->type == USER_SUCCESS)
  164.  
    {
  165.  
    printf("%s\n",head->word);
  166.  
    sprintf(time,"current time:%s\n%s\n",ctime(&t),head->word);//获得当前时间
  167.  
    write(fd,time,strlen(time));
  168.  
    printf("%s\n",time);
  169.  
    return 0;
  170.  
    }
  171.  
    else
  172.  
    {
  173.  
    printf("\nno such word!\n");
  174.  
    }
  175.  
    close(fd);
  176.  
    return 0;
  177.  
    }
  178.  
     
  179.  
     
  180.  
    int do_history(int sockfd)
  181.  
    {
  182.  
    int n = 0;
  183.  
    char buf[1024] = {0};
  184.  
    int fd;
  185.  
    fd = open("history.txt",O_RDONLY);
  186.  
    while(1)
  187.  
    {
  188.  
    memset(buf,0,sizeof(buf));
  189.  
    n = read(fd,buf,sizeof(buf));
  190.  
    if(0 == n)
  191.  
    break;
  192.  
    printf("%s",buf);
  193.  
    }
  194.  
    close(fd);
  195.  
    return 0;
  196.  
    }
  197.  
    int do_task2(int sockfd)
  198.  
    {
  199.  
    int cmd;
  200.  
    while(1)
  201.  
    {
  202.  
    //提示界面帮助,用户选择
  203.  
    help_info2();
  204.  
     
  205.  
    printf("\n\n请选择>");
  206.  
    scanf("%d",&cmd);
  207.  
    //吃掉回车键
  208.  
    getchar();
  209.  
    switch(cmd)
  210.  
    {
  211.  
    //查询单词函数
  212.  
    case QUERY:
  213.  
    if(do_query(sockfd) < 0)
  214.  
    continue;
  215.  
    break;
  216.  
    //查询历史函数
  217.  
    case HISTORY:
  218.  
    if(do_history(sockfd) < 0)
  219.  
    continue;
  220.  
    break;
  221.  
    case QUIT:
  222.  
    exit(EXIT_SUCCESS);
  223.  
    default:
  224.  
    printf("Unknow cmd.\n");
  225.  
    continue;
  226.  
    }
  227.  
    }
  228.  
    return 0;
  229.  
    }
  230.  
     
  231.  
    int do_login(int sockfd)
  232.  
    {
  233.  
    int n = 0;
  234.  
    int count = 0;
  235.  
    char buf[1024] = {0};
  236.  
    //定义发送的协议头
  237.  
    mhead_t *head = (mhead_t *)buf;
  238.  
     
  239.  
    printf("\n您正在登录,请输入用户名和密码\n");
  240.  
     
  241.  
    head->type = USER_LOGIN;
  242.  
    head->size = sizeof(mhead_t);
  243.  
    printf("Input username : ");
  244.  
    fgets(head->username,sizeof(head->username),stdin);
  245.  
    head->username[strlen(head->username) - 1] = '\0';
  246.  
     
  247.  
    printf("Input password : ");
  248.  
    fgets(head->password,sizeof(head->password),stdin);
  249.  
    head->password[strlen(head->password) - 1] = '\0';
  250.  
     
  251.  
    //发给服务器端
  252.  
     
  253.  
    if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
  254.  
    {
  255.  
    perror("Fail to send");
  256.  
    exit(EXIT_FAILURE);
  257.  
    }
  258.  
    bzero(&buf,sizeof(buf));
  259.  
    while(1)
  260.  
    {
  261.  
    //接收数据,TCP是可靠的连接,若是数据
  262.  
    //未完全接收的话,可以在接收
  263.  
    n = recv(sockfd,buf count,sizeof(mhead_t) - count,0);
  264.  
     
  265.  
    if(n <= 0){
  266.  
    perror("Fail to send");
  267.  
    exit(EXIT_FAILURE);
  268.  
    }
  269.  
    //若是数据未发送完成,再次接收的时候可补充
  270.  
    count = n;
  271.  
    if(count == sizeof(mhead_t))
  272.  
    break;
  273.  
    }
  274.  
     
  275.  
    if(head->type == USER_SUCCESS)
  276.  
    {
  277.  
    printf("\n恭喜您,登录成功!\n");
  278.  
    return 0;
  279.  
    }else{
  280.  
    printf("\n登陆用户信息错误,请重试!\n");
  281.  
    return -1;
  282.  
    }
  283.  
    }
  284.  
    int do_task(int sockfd)
  285.  
    {
  286.  
    int cmd;
  287.  
    while(1)
  288.  
    {
  289.  
    //提示界面帮助,用户选择
  290.  
    help_info1();
  291.  
     
  292.  
    printf("\n\n请选择>");
  293.  
    scanf("%d",&cmd);
  294.  
    //吃掉回车键
  295.  
    getchar();
  296.  
    switch(cmd)
  297.  
    {
  298.  
    //用户登陆
  299.  
    case LOGIN:
  300.  
    if(do_login(sockfd) < 0)
  301.  
    continue;
  302.  
    do_task2(sockfd);
  303.  
    break;
  304.  
    //用户注册,我们先来写注册的函数
  305.  
    case REGISTER:
  306.  
    if(do_register(sockfd) < 0)
  307.  
    continue;
  308.  
    do_task2(sockfd);
  309.  
    break;
  310.  
    case QUIT:
  311.  
    exit(EXIT_SUCCESS);
  312.  
    default:
  313.  
    printf("Unknow cmd.\n");
  314.  
    continue;
  315.  
    }
  316.  
    }
  317.  
    return 0;
  318.  
    }
  319.  
     
  320.  
    //./client ip port
  321.  
    //由于后面要传递参数,故这里的const省略
  322.  
    int main(int argc, char *argv[])
  323.  
    {
  324.  
    int sockfd;
  325.  
    int addr_len = sizeof(struct sockaddr);
  326.  
    struct sockaddr_in peer_addr;
  327.  
     
  328.  
    if(argc < 3)
  329.  
    {
  330.  
    fprintf(stderr,"Usage : %s argv[1] argv[2]\n",argv[0]);
  331.  
    exit(EXIT_FAILURE);
  332.  
    }
  333.  
     
  334.  
    sockfd = init_tcp(argv[1],argv[2]);
  335.  
     
  336.  
    do_task(sockfd);
  337.  
     
  338.  
    return 0;
  339.  
    }
学新通

九、运行结果

1、先运行服务器

学新通

2、再运行客户端

 学新通

 3、登陆

学新通

4、 查询单词

学新通

5、查询历史记录

学新通

 6、退出

学新通

 7、注册

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkijge
系列文章
更多 icon
同类精品
更多 icon
继续加载