操作系统课程设计

一、课程设计目标与任务

目的:熟悉linux下socket、网络编程的基本方法,掌握实现客户/服务器程序的编写方法;

任务:编写一个简单的程序,该程序可实现基于TCP协议的简单的客户/服务器方式。

 

二、涉及的主要理论及算法思想

TCP协议,socket、网络编程

 

三、具体设计及开发思路

编写两个程序,一个客户端,一个服务器,使两个程序建立socket连接,以相互传送数据。

 

四、代码

Client:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define port 8888

int main()
{
        //一、创建套接字socket
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1)
        {
                perror("socket failed");
                exit(-1);
        }

        //二、准备通信地址
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;      //指定协议族,和socket()的参数保持一致
        addr.sin_port = htons(port);    //设置网络通信使用的端口号
        inet_aton("192.168.1.129", &addr.sin_addr);     //存储网络通信用ip地址

        //三、连接服务器
        int con = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
        if (con == -1)
        {
                perror("connect failed");
                exit(-1);
        }
        printf("连接成功!\n");

        //四、与服务器交换数据
        char buf[100] = {0};
        char *str = "hello server.";
        send(sockfd, str, strlen(str), 0);
        recv(sockfd, buf, sizeof(buf), 0);
        printf("收到来自服务器的信息:%s\n", buf);

        //五、关闭连接
        close(sockfd);

        return 0;
}

 

Server

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define port 8888

int main()
{
        //一、创建套接字
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1)
        {
                perror("socket failed");
                exit(-1);
        }

        //二、准备通信地址
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        inet_aton("192.168.1.129", &addr.sin_addr);

        //三、绑定socket和通信地址
       int bin = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
        if (bin == -1)
        {
                perror("bind failed");
                exit(-1);
        }

         //四、监听端口
         bin = listen(sockfd, 100);
         if (bin == -1)
         {
                perror("listen failed");
                exit(-1);
         }
         printf("开始监听%d端口...\n", port);

         //五、处理连接请求
         struct sockaddr_in fromaddr;
         socklen_t len = sizeof(fromaddr);
         int clientfd = accept(sockfd, (struct sockaddr *)&fromaddr, &len);
         if (clientfd == -1)
         {
                perror("accept failed");
                exit(-1);
         }
          printf("%s连接\n", inet_ntoa(fromaddr.sin_addr));
          //六、处理客户端数据
        char buf[100] = {0};
          recv(clientfd, buf, sizeof(buf), 0);
          printf("客户端:%s\n", buf);
          char *str = "hello client.";
          send(clientfd, str, strlen(str), 0);

          //七、关闭连接
          close(clientfd);
          close(sockfd);

          return 0;
}

 

五、程序运行效果展示截图

 

六、技术小结

1.基于TCP的网络编程:

    基于连接, 在交互过程中, 服务器和客户端要保持连接, 不能断开。重发一切出错数据、数据验证, 保证数据的正确性、完整性和顺序性,

    缺点是消耗的资源比较大。

2.编程步骤:

    服务器:

      ① 创建socket(套接字) socket()

      ② 准备通信地址

      ③ 将创建的socket和通信地址绑定 bind()

      ④ 监听端口 listen()

      ⑤ 等待客户端连接 accpet()

      ⑥ 通信双方收发数据 read()/write()

                 send()/recv()

      ⑦ 关闭socket

    客户端:

      ① 创建socket(套接字) socket()

      ② 准备通信地址

      ③ 连接服务器 connect()

      ④ 收发数据 read()/write()

             send()/recv()

      ⑤ 关闭socket 

3. API详解

(1) socket()函数

    int socket(domain, type, protocol)

    domain:

        AF_UNIX/AF_LOCAL/AF_FILE: 本地通信

        AF_INET: 网络通信 ipv4

        AF_INET6: 网络通信 ipv6

        注:如果AF换成PF效果一样

    type, 选择通信类型, 主要包括:

        SOCK_STREAM: TCP

        SOCK_DGRAM : UDP

    protocol, 本来应该指定通信协议, 但现在基本废弃, 因为协议已经在前面两个参数指定完成,给0即可

(2) bind()函数

    int bind(int sockfd, struct sockaddr *addr, size)

    sockfd: 要绑定的套接字描述符

size: 第二个参数占据的内存空间大小

    addr: 涉及三个数据结构struct sockaddr, sockaddr_un, sockaddr_in

     sockaddr, 主要用于函数参数, 不负责存储数据

     sockaddr_un, 当着本地通信时, 用于本地通信使用的地址 (sys/un.h)

     sockaddr_in, 当着网络通信时, 负责存储网络通信的地址数据

     struct sockaddr_in

{

         sin_family; //用于指定协议族, 和socket()的参数保持一致

         sin_port; //网络通信使用的端口号

         sin_addr; //存储网络通信的ip地址 

     }

(3) listen()函数

    int listen(int sockfd, int backlog)

     sockfd: 将sockfd参数所标识的套接字为被动模式, 使之可以接受连接请求

     backlog: 表示未决连接请求队列的最大长度, 即允许最多有多少个未决连接请求存在。若服务器的未决连接请求已达到该值, 则客户端通过 connect()连接服务器的操作将返回-1,且error为ECONNREFUSED

(4) accpet()函数

    int accpet(sockfd, struct sockaddr* addr, socklen_t *addrlen)

     从sockfd参数所标识套接字对应未决连接请求队列中取出的一个连接请求, 同时创建一个新的套接字,用于该连接通信, 返回套接字的描述符

     addr和addrlen 用于输出连接请求发起者的地址信息

     返回值: 为新创建用于和客户端通信的套接字描述符 失败-1, error

(5) recv()函数  

   int recv(int sockfd, buf, len, flags)

     flags, 通常取0: 阻塞收取数据

        O_NONBLOCK: 不阻塞, 如果未收到数据, 返回错误信息

     返回值:

        >0, 实际接受数据字节数

        -1 , 出错, error

         0 , 通信的另一端关闭

(6)send()函数

   int send(int sockfd, buf, len, flags)

     flags: 通常取0, 阻塞发送

     O_NONBLOCK: 不阻塞, 如果未收到数据, 返回错误信息

(7) connect()函数

   int connect(int sockfd, addr, addr_len)

     参数参考bind()

 

https://www.cnblogs.com/findumars/p/8030439.html

转载于:https://www.cnblogs.com/rnss/p/10993530.html

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
设计一: 设计任务:模拟Linux文件系统 在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的模拟Linux文件系统。 1. 在现有机器硬盘上开辟100M的硬盘空间,作为设定的硬盘空间。 2. 编写一管理程序simdisk对此空间进行管理,以模拟Linux文件系统,要求: (1) 盘块大小1k (2) 空闲盘块的管理:Linux位图法 (3) 结构:超级块, i结点区, 根目录区 3. 该simdisk管理程序的功能要求如下: (1) info: 显示整个系统信息(参考Linux文件系统的系统信息),文件可以根据用户进行读写保护。目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开。 (2) cd …: 改变目录:改变当前工作目录,目录不存在时给出出错信息。 (3) dir …: 显示目录:显示指定目录下或当前目录下的信息,包括文件名、物理地址、保护码、文件长度、子目录等(带/s参数的dir命令,显示所有子目录)。 (4) md …: 创建目录:在指定路径或当前路径下创建指定目录。重名时给出错信息。 (5) rd …: 删除目录:删除指定目录下所有文件和子目录。要删目录不空时,要给出提示是否要删除。 (6) newfile …: 建立文件。 (7) cat …: 打开文件。 (8) copy …: 拷贝文件,除支持模拟Linux文件系统内部的文件拷贝外,还支持host文件系统与模拟Linux文件系统间的文件拷贝,host文件系统的文件命名为<host>…,如:将windows下D:盘的文件\data\sample\test.txt文件拷贝到模拟Linux文件系统中的/test/data目录,windows下D:盘的当前目录为D:\data,则使用命令: simdisk copy <host>D:\data\sample\test.txt /test/data 或者:simdisk copy <host>D:sample\test.txt /test/data (9) del …: 删除文件:删除指定文件,不存在时给出出错信息。 (10) check: 检测并恢复文件系统:对文件系统中的数据一致性进行检测,并自动根据文件系统的结构和信息进行数据再整理。 4. 程序的总体流程为: (1) 初始化文件目录; (2) 输出提示符,等待接受命令,分析键入的命令; (3) 对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令,直到键入EXIT退出为止。 设计二: 设计任务:模拟文件系统的前端操作shell 实现一个简单的shell(命令行解释器)。 将设计一的管理程序simdisk作为后台进程运行,利用本设计任务的shell操作simdisk。 本设计任务在于学会如何实现在前端的shell进程和后端的simdisk进程之间利用共享内存进行进程间通信(IPC)。 设计三: 设计任务:模拟文件系统的操作管理 实现多个进程同时对模拟文件系统进行操作。设计管理程序simdisk的用户访问权限管理。访问模拟文件系统的每个进程都属于某个用户,管理程序simdisk根据其访问权限决定其对模拟文件系统的操作。 对模拟文件系统的操作要求做到:共享读,互斥写。 本设计任务在于学会如何实现信息的安全管理和进程同步。 注:要求从课程设计的整体来考虑设计任务一、二、三,并分阶段实现。
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页