2024.1.17 网络编程 作业

发布时间:2024年01月17日

思维导图

练习题

广播服务器端

#include <myhead.h>

int main(int argc, char const *argv[])
{
    //创建套接字
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    //填充网络信息结构体
    struct sockaddr_in cin;
    cin.sin_family = AF_INET;
    cin.sin_port = htons(6789);
    cin.sin_addr.s_addr = inet_addr("192.168.124.255");
    //绑定
    bind(sfd, (struct sockaddr *)&cin, sizeof(cin));
    char buf[128] = "";
    //接收广播消息
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL);
        printf("接收到的消息:%s\n",buf);
    }
    //关闭套接字
    close(sfd);
    return 0;
}

广播客户端

#include <myhead.h>

int main(int argc, char const *argv[])
{
    //创建套接字
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    //将套接字设置成允许广播
    int broadcase = 1;
    if (setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &broadcase, sizeof(broadcase)) == -1)
    {
        perror("setsockopt error");
        return -1;
    }
    //填充网络信息结构体
    struct sockaddr_in cin;
    cin.sin_family = AF_INET;
    cin.sin_port = htons(6789);
    cin.sin_addr.s_addr = inet_addr("192.168.124.255");
    //绑定非必要
    //bind(sfd, (struct sockaddr *)&cin, sizeof(cin));
    char buf[128] = "";
    //发送广播消息
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        printf("请输入--->");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1]='\0';
        //发送到广播地址中去
        sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, sizeof(cin));
        printf("发送成功\n");
    }

    close(sfd);
    return 0;
}

组播服务器端

#include <myhead.h>

int main(int argc, char const *argv[])
{
    //创建套接字
    int rfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (rfd == -1)
    {
        perror("socket error");
        return -1;
    }
    //设置网络属性
    struct ip_mreqn im;
    im.imr_multiaddr.s_addr = inet_addr("224.1.2.3");
    im.imr_address.s_addr = inet_addr("192.168.125.193");
    im.imr_ifindex = 2;

    if (setsockopt(rfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &im, sizeof(im)) == -1)
    {
        perror("setsockopt error");
        return -1;
    }
    puts("加入多播组成功");
    //填充地址信息结构体
    struct sockaddr_in rin;
    rin.sin_family = AF_INET;
    rin.sin_port = htons(9999);
    rin.sin_addr.s_addr = inet_addr("224.1.2.3");
    //绑定
    if (bind(rfd, (struct sockaddr *)&rin, sizeof(rin)) == -1)
    {
        perror("绑定成功");
        return -1;
    }
    puts("绑定成功");
    //接收消息
    char buf[128]="";
    while(1)
    {
        memset(buf,0,sizeof(buf));
        recvfrom(rfd,buf,sizeof(buf),0,0,0);
        printf("收到消息为:%s\n",buf);
    }
    //关闭套接字
    close(rfd);
    return 0;
}

组播客户端

#include <myhead.h>

int main(int argc, char const *argv[])
{
    //创建套接字
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sfd == -1)
    {
        perror("socket error");
        return -1;
    }
    //发送端不用设置网络属性

    //填充地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(9999);
    sin.sin_addr.s_addr = inet_addr("224.1.2.3");
    //绑定非必要
    /*
    if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
    {
        perror("绑定成功");
        return -1;
    }
    puts("绑定成功");
    */
    //发送消息
    char buf[128] = "";
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = 0;
        //发送给指定IP端口
        sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin));
        printf("收到消息为:%s\n", buf);
    }
    //关闭套接字
    close(sfd);
    return 0;
}

流式域套接字

? ? ? 服务器端

#include <myhead.h>

int main(int argc, const char *argv[])
{
    //1、创建套接字
    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    //int sfd = socket(AF_UNIX, SOCK_RAW, IPPROTO_TCP);
    if (sfd == -1)
    {
        perror("socket error");
        return -1;
    }
    //由于域套接字的绑定函数,只能绑定一个不存在的套接字文件
    //所以,在绑定之前需要判断当前文件是否存在
    if (access("./unix", F_OK) == 0)
    {
        //表示文件存在,删除该文件
        if (unlink("./unix") == -1)
        {
            perror("unlink error");
            return -1;
        }
    }
    //2、填充地址信息结构体
    struct sockaddr_un sun;
    sun.sun_family = AF_UNIX; //通信域
    //sun.sun_path = ".unix";            //字符串赋值不能使用赋值运算符
    strcpy(sun.sun_path, "./unix"); //绑定套接字文件
    //3、绑定地址信息结构体
    if (bind(sfd, (struct sockaddr *)&sun, sizeof(sun)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");
    //4、监听
    if (listen(sfd, 128) == -1)
    {
        perror("listen error");
        return -1;
    }
    //5、阻塞接收客户端链接请求
    //定义容器接收客户端地址信息结构体
    struct sockaddr_un cun;
    socklen_t socklen = sizeof(cun);
    int newfd = accept(sfd, (struct sockaddr *)&cun, &socklen); //表示不接收客户端地址信息
    if (newfd == -1)
    {
        perror("accept error");
        return -1;
    }
    //6、收发数据
    char buf[128] = "";
    while (1)
    {
        //清空数组
        bzero(buf, sizeof(buf));
        int res = recv(newfd, buf, sizeof(buf), 0); //读取消息
        if (res == 0)
        {
            printf("客户端已经下线\n");
            break;
        }
        printf("[%s]: %s\n", cun.sun_path, buf);
    }
    //7、关闭套接字
    close(newfd);
    close(sfd);

    return 0;
}

? ? ? ? ?客户端

#include <myhead.h>

int main(int argc, char const *argv[])
{
    //创建套接字
    int cfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (cfd == -1)
    {
        perror("socket error");
        return -1;
    }
    //判断Linux文件是否存在
    if (access("./linux", F_OK) == 0)
    {
        if (unlink("./linux") == -1)
        {
            perror("unlink error");
            return -1;
        }
    }
    //填充信息结构体
    struct sockaddr_un cun;
    cun.sun_family = AF_UNIX;
    strcpy(cun.sun_path, "./linux");
    //绑定信息结构体
    if (bind(cfd, (struct sockaddr *)&cun, sizeof(cun)) == -1)
    {
        perror("bind error");
        return -1;
    }
    puts("bind success");

    //连接服务器
    //填充服务器地址信息结构体
    struct sockaddr_un sun;
    sun.sun_family = AF_UNIX;
    strcpy(sun.sun_path, "./unix");
    //连接服务器
    connect(cfd, (struct sockaddr *)&sun, sizeof(sun));
    //收发数据
    char buf[128] = "";
    while (1)
    {
        //清空数组
        memset(buf, 0, sizeof(buf));
        //获取消息内容
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = 0;
        //发送消息
        send(cfd, buf, sizeof(buf), 0);
        printf("发送成功\n");
        if (strcmp(buf, "quit") == 0)
        {
            break;
        }
    }
    //关闭套接字
    close(cfd);
    return 0;
}

报式域套接字

? ? ? 服务器端

#include<myhead.h>

int main(int argc, const char *argv[])
{
    //创建套接字
    int sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("sfd = %d\n", sfd);
    //由于域套接字的绑定函数,只能绑定一个不存在的套接字文件
    //所以,在绑定之前需要判断当前文件是否存在
    if(access("./linux", F_OK) == 0)
    {   
        //表示文件存在,删除该文件
        if(unlink("./linux")==-1)
        {
            perror("unlink error");
            return -1; 
        }
    }     
    // 填充地址信息结构体
    struct sockaddr_un sun;
    sun.sun_family = AF_UNIX;
    strcpy(sun.sun_path, "./linux");
    // 绑定工作
    if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
    {
        perror("bind error");
        return -1;
    }
    //数据收发
    char buf[128] = "";
    //定义变量存放客户端地址信息结构体
    struct sockaddr_un cun;
    socklen_t socklen = sizeof(cun);
    while(1)
    {
        //清空数组
        bzero(buf, sizeof(buf));
        //从套接字文件中读取消息
        recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cun, &socklen);
        printf("[%s]:%s\n", cun.sun_path, buf);
        //将字符串连接后回发
        strcat(buf, "*.*");
        //if(write(sfd, buf, sizeof(buf)) == -1)
        if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cun, sizeof(cun)) == -1)
        {
            perror("sendto error");
            return -1;
        }
        printf("发送成功\n");
    }
    //4、关闭套接字
    close(sfd);
    return 0;
}

? ? ? ? ?客户端

#include <myhead.h>

int main(int argc, const char *argv[])
{
    //1、创建用于通信的套接字文件描述符
    int cfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (cfd == -1)
    {
        perror("socket error");
        return -1;
    }

    //由于域套接字的绑定函数,只能绑定一个不存在的套接字文件
    //所以,在绑定之前需要判断当前文件是否存在
    if (access("./unix", F_OK) == 0)
    {
        //表示文件存在,删除该文件
        if (unlink("./unix") == -1)
        {
            perror("unlink error");
            return -1;
        }
    }

    //2、绑定
    //2.1 填充地址信息结构体
    struct sockaddr_un cun;
    cun.sun_family = AF_UNIX;
    strcpy(cun.sun_path, "./unix");

    //2.2 绑定工作
    if (bind(cfd, (struct sockaddr *)&cun, sizeof(cun)) == -1)
    {
        perror("bind error");
        return -1;
    }

    //3、填充服务器的地址信息结构体
    struct sockaddr_un sun;
    sun.sun_family = AF_UNIX;
    strcpy(sun.sun_path, "./linux");

    //4、数据收发
    char buf[128] = "";
    while (1)
    {
        printf("请输入>>>");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = '\0';

        //发送给服务器
        sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr *)&sun, sizeof(sun));

        if (strcmp(buf, "quit") == 0)
        {
            break;
        }

        //接收服务器发送来的消息
        recvfrom(cfd, buf, sizeof(buf), 0, NULL, NULL);
        printf("收到消息:%s\n", buf);
    }

    //5、关闭套接字
    close(cfd);

    return 0;
}

使用TFTP协议完成客户端的文件上传下载功能

#include <myhead.h>
int fileonload(int sockfd)
{
    int sfd = sockfd;
    printf("上传的文件:");
    char file[64];
    scanf("%s", file);
    //打开文件用于读取上传文件的数据
    int send_fd = -1;
    if ((send_fd = open(file, O_RDONLY)) == -1)
    {
        perror("open error:");
        return -1;
    }
    //填充信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(69);
    sin.sin_addr.s_addr = inet_addr("192.168.125.60");
    socklen_t socklen = sizeof(sin);

    //封装请求下载数据包
    //第一块
}
int main(int argc, char const *argv[])
{
    // 创建套接字UDP通信
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == sockfd)
    {
        perror("socket error");
        return -1;
    }
    // 填充服务器网络信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    //端口号填69
    sin.sin_port = htons(69);
    //填写windows ip地址
    sin.sin_addr.s_addr = inet_addr("192.168.125.60");
    //结构体长度
    socklen_t socklen = sizeof(sin);

    //数据包数据的长度以512字节传输
    char buffer[516] = {0};
    //返回的ACK
    char ack[4];
    //操作码
    short code = 0;
    //块编号 or 错误码
    short BlockoErr = 0;
    //数据的长度以512Byte传输
    char text[512] = {0}; //文件内容 或 错误信息
    //校验收到的块编号
    int N = 0;
    //返回的文件描述符
    int fd;
    int ret = 0;
    //文件名
    char filename[64] = {0};
    while (1)
    {
        int chose = 0;
        puts("1.下载");
        puts("2.上传");
        puts("3.退出");
        scanf("%d", &chose);
        switch (chose)
        {
        case 1:
            memset(filename, 0, sizeof(filename));
            //输入文件名
            printf("下载文件名: ");
            scanf("%s", filename);
            //使用 sprintf 组包
            //返回成功格式化字符的个数  01下载操作 10上传操作
            ret = sprintf(buffer, "%c%c%s%c%s%c", 0, 1, filename, 0, "octet", 0);
            //首次发送请求
            if (-1 == sendto(sockfd, buffer, ret, 0, (struct sockaddr *)&sin, socklen))
            {
                perror("sendto error");
                return -1;
            }
            //循环接收服务器发来的数据包
            while (1)
            {
                //因为有临时端口需要保存服务器的网络信息结构体
                ret = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&sin, &socklen);
                if (-1 == ret)
                {
                    perror("recvfrom error");
                    return -1;
                }
                //解析操作码
                code = ntohs(*(short *)buffer);
                //解析块编号or错误码
                BlockoErr = ntohs(*(short *)(buffer + 2));
                //解析文件内容or错误信息,并将内容放入数据段
                strncpy(text, buffer + 4, sizeof(text));
                //解析数据包中的内容
                if (3 == code && BlockoErr == N + 1)
                {
                    //校验块编号+1
                    N++;
                    //要接收的数据包
                    //如果是第一次接到数据包 要创建文件
                    if (BlockoErr == 1)
                    {
                        fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
                        if (-1 == fd)
                        {
                            perror("open error");
                        }
                    }
                    //将文件内容写入文件 留出4字节
                    if (-1 == write(fd, text, ret - 4))
                    {
                        perror("write error");
                    }
                    // 组装ACK
                    *(short *)ack = htons(4);
                    *(short *)(ack + 2) = htons(BlockoErr);
                    //回复ACK包
                    if (-1 == sendto(sockfd, ack, 4, 0, (struct sockaddr *)&sin, socklen))
                    {
                        perror("recvfrom error");
                    }
                    //文件接收完毕
                    if (ret < 512)
                        break;
                }
            }
            printf("文件[%s]下载完成\n", filename);
            close(sockfd);
            break;
        case 2:
            memset(filename, 0, sizeof(filename));
            //输入文件名
            printf("上传文件名: ");
            scanf("%s", filename);
            int upfd = -1;
            if ((upfd = open(filename, O_RDONLY)) == -1)
            {
                perror("open error:");
                return -1;
            }
            short *p1 = (short *)buffer;
            *p1 = htons(2);
            //第二模块
            char *p2 = buffer + 2;
            strcpy(p2, filename);
            //第三模块
            char *p3 = p2 + strlen(p2) + 1;
            strcpy(p3, "octet");
            int len = 4 + strlen(p2) + strlen(p3);
            sendto(sockfd, buffer, len, 0, (struct sockaddr *)&sin, sizeof(sin));

            char *data_point = buffer + 4;
            short *cmd_point = (short *)buffer;
            *cmd_point = htons(3);
            short *block_point = (short *)(buffer + 2);
            *block_point = htons(1);
            int i = 1;
            while (1)
            {
                recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&sin, &socklen);
                if (*cmd_point == htons(4))
                {
                    int res = read(upfd, buffer + 4, 512);
                    if (res == 0)
                    {
                        break;
                    }
                    *cmd_point = htons(3);
                    sendto(sockfd, buffer, res + 4, 0, (struct sockaddr *)&sin, socklen);
                }
            }
            printf("文件[%s]上传完成\n", filename);
            close(sockfd);
            break;
        case 3:
            exit(0);
        default:
            puts("error");
        }
    }

    return 0;
}

文章来源:https://blog.csdn.net/m0_63196682/article/details/135658015
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。