利用TCP通信实现文件传输和通信

news2024/11/27 9:42:22

前言

我们上一章已经熟悉了理论知识,这一章来练习一下

1.实现文件的传输

1.1 客户端

dir_client.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>



//服务端和客户端通信,实现文件的发送(但是服务单只负责接收,客户端负责发送)
//客户端程序

int main(int argc,char** argv)
{
    //1.创建待连接套接字
    int socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2.绑定套接字与网络地址
    //第二个参数需要这个结构体
    struct sockaddr_in s_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[2]));//设置端口//主机字节序的短整型数据,atoi将字符串转为整形
    s_addr.sin_addr.s_addr = inet_addr(argv[1]);//将点分十进制转为无符号的32位网络地址

    int bind_ok = bind(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    if(bind_ok==-1){
        perror("bind failed");
    }


    //3.请求连接
    int socket_ok = connect(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    if(socket_ok==-1){
        perror("连接失败\n");
        return -1;
    }

    //开始文件传输吧
    //打开一个文件
    int fd  = open("./1.txt",O_RDWR);
    if(fd==-1){
        perror("文件打开失败");
        return -1;
    }
    
    char buf[128];
    while(1){

        memset(buf,0,sizeof(buf));

        //读取文件内容
        ssize_t n = read(fd,buf,sizeof(buf)-1);

        //发送文件的内容
        send(socket_fd,buf,sizeof(buf),0);

        if(n==0){
            printf("—————发送文件成功—————\n");
            close(fd);
            break;
        }

    }

    close(socket_fd);
    return 0;
}

1.2 服务端

dir_server.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

//服务端和客户端通信,实现文件的发送(但是服务单只负责接收,客户端负责发送)
//服务端程序

int main(int argc,char** argv)
{
    //1.创建待连接套接字
    int socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2.绑定套接字与网络地址
    //第二个参数需要这个结构体
    struct sockaddr_in s_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[2]));//设置端口 //主机字节序的短整型数据 ,atoi将字符串转为整形
    s_addr.sin_addr.s_addr = inet_addr(argv[1]);//将将点分十进制转转为无符号的32位网络地址

    int bind_ok = bind(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    if(bind_ok==-1){
        perror("bind failed");
    }

    //3.设置监听
    int socket_listen = listen(socket_fd,4);
    if(socket_listen==-1){
        perror("监听失败");
        return -1;
    }

    //4.等待对端连接请求
    printf("等待连接\n");
    int socket_ok = accept(socket_fd,NULL,NULL);
    if(socket_ok==-1){
        perror("连接失败\n");
        return -1;
    }
    printf("连接成功\n");

    //开始接收文件
    //创建一个文件
    int fd2  = open("./2.txt",O_WRONLY | O_CREAT,0777);
    if(fd2==-1){
        perror("文件打开失败");
        return -1;
    }

    char buf[128];
    while(1){
        memset(buf,0,sizeof(buf));
        //5.接收文件
        recv(socket_ok,buf,sizeof(buf),0);//阻塞等待

        //将文件内容写入另一个文件,实现文件的传输
        ssize_t n = write(fd2,buf,strlen(buf));

        //退出
        if(n==0){
            printf("————接收文件成功————\n");
            close(fd2);
            break;
        }
        
    }
    close(socket_fd);
    close(socket_ok);
    return 0;
}

2. 实现服务客户端的双向通信

shuangxiang_server.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>


//服务端和客户端双向通信
//服务端程序
int socket_ok = -1;

void* fasong(void* arg){
    char msg[128];

    while(1){
        memset(msg,0,sizeof(msg));

        fgets(msg,sizeof(msg),stdin);//键盘输入
        //发送数据
        send(socket_ok,msg,sizeof(msg),0);
        printf("服务端发送:%s",msg);

        //退出
        if(strcmp("bye\n",msg)==0){
            break;
        }

    }
}


int main(int argc,char** argv)
{
    //1.创建待连接套接字
    int socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2.绑定套接字与网络地址
    //第二个参数需要这个结构体
    struct sockaddr_in s_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[2]));//设置端口 //主机字节序的短整型数据
    s_addr.sin_addr.s_addr = inet_addr(argv[1]);//将将点分十进制转转为无符号的32位网络地址

    int bind_ok = bind(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    if(bind_ok==-1){
        perror("bind failed");
    }

    //3.设置监听
    int socket_listen = listen(socket_fd,4);
    if(socket_listen==-1){
        perror("监听失败");
        return -1;
    }

    //4.等待对端连接请求
    printf("等待连接\n");
    struct sockaddr_in c_addr;//保存客户端地址信息
    socklen_t size_len = sizeof(c_addr);//因为第三个参数需要socklen_t类型,所以我们提前转一下类型
    socket_ok = accept(socket_fd,(struct sockaddr*)&c_addr,&size_len);
    if(socket_ok==-1){
        perror("连接失败\n");
        return -1;
    }
    printf("连接成功\n");

    //开始畅聊吧
    //创建线程
    pthread_t tid;
    pthread_create(&tid,NULL,&fasong,NULL);

    char buf[128];
    while(1){
        memset(buf,0,sizeof(buf));
        //5.接收消息
        recv(socket_ok,buf,sizeof(buf),0);//阻塞等待
        printf("服务端接收到:%s",buf);

        //退出
        if(strcmp("bye\n",buf)==0){
            break;
        }
    }
    close(socket_fd);
    close(socket_ok);
    return 0;
}

shuangxiang_client.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>


//服务端和客户端双向通信
//客户端程序
int socket_fd = -1;

void* jieshou(void* arg){

    char msg[128];
    while(1){
        memset(msg,0,sizeof(msg));
        //5.接收消息
        recv(socket_fd,msg,sizeof(msg),0);//阻塞等待
        printf("客户端接收到:%s",msg);

        //退出
        if(strcmp("bye\n",msg)==0){
            break;
        }
    }
}


int main(int argc,char** argv)
{
    //1.创建待连接套接字
    socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2.绑定套接字与网络地址
    //第二个参数需要这个结构体
    struct sockaddr_in s_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[2]));//设置端口//主机字节序的短整型数据
    s_addr.sin_addr.s_addr = inet_addr(argv[1]);//将点分十进制转为无符号的32位网络地址

    int bind_ok = bind(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    if(bind_ok==-1){
        perror("bind failed");
    }


    //3.请求连接
    connect(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    

    //开始畅聊吧
    //创建线程
    pthread_t tid;
    pthread_create(&tid,NULL,&jieshou,NULL);

    char buf[128];
    while(1){

        memset(buf,0,sizeof(buf));

        fgets(buf,sizeof(buf),stdin);//从键盘获取输入
        //发送消息
        send(socket_fd,buf,sizeof(buf),0);
        printf("客户端发送:%s",buf);

        //退出
        if(strcmp("bye\n",buf)==0){
            break;
        }
    }

    close(socket_fd);
    return 0;
}

3. 实现多个客户端和服务端通信

more_one_server.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>


//多个客户端通信和服务端单向通信
//服务端程序

//自己创建的结构体,用于保存已连接套接字,和客户端端口号
struct message{
    unsigned short port;
    int socket_ok1;  
};

void* jieshou(void* arg){

    char msg[128];

    //取出客户端端口号
    // unsigned short* port = (unsigned short*)arg;

    //取出客户端端口号
    // unsigned short* port = calloc(1,2);
    // port = (unsigned short*)arg;

    //取出客户端的信息
    struct message* ms = (struct message*)arg;
    unsigned short port1 = ms->port;
    int socket_ok = ms->socket_ok1;

    while(1){

        memset(msg,0,sizeof(msg));
        //接收数据
        recv(socket_ok,msg,sizeof(msg),0);

        printf("服务端接收到端口号为%u:%s",port1,msg);

        //退出
        if(strcmp("bye\n",msg)==0){
            break;
        }

    }
}


int main(int argc,char** argv)
{
    //1.创建待连接套接字
    int socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2.绑定套接字与网络地址
    //第二个参数需要这个结构体
    struct sockaddr_in s_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[2]));//设置端口 //主机字节序的短整型数据
    s_addr.sin_addr.s_addr = inet_addr(argv[1]);//将将点分十进制转转为无符号的32位网络地址

    int bind_ok = bind(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    if(bind_ok==-1){
        perror("bind failed");
    }

    //3.设置监听
    int socket_listen = listen(socket_fd,4);
    if(socket_listen==-1){
        perror("监听失败");
        return -1;
    }

    

    //开始畅聊吧
    //创建线程
    pthread_t tid;
    
    int socket_ok;
    char buf[128];
    while(1){

        //4.等待对端连接请求
        printf("等待连接\n");
        struct sockaddr_in c_addr;//保存客户端地址信息
        socklen_t size_len = sizeof(c_addr);//因为第三个参数需要socklen_t类型,所以我们提前转一下类型
        socket_ok = accept(socket_fd,(struct sockaddr*)&c_addr,&size_len);
        if(socket_ok==-1){
            perror("连接失败\n");
            return -1;
        }
        printf("连接成功\n");


        //取出客户端端口号
        // unsigned short* port = calloc(1,2);
        // *port = ntohs(c_addr.sin_port);

        //取出客户端端口号
        // unsigned short p = ntohs(c_addr.sin_port);//取出客户端端口号
        // short* port = &p;


        //自己创建的结构体,用于保存已连接套接字,和客户端端口号
        struct message ms;
        ms.port = ntohs(c_addr.sin_port);
        ms.socket_ok1 = socket_ok;
        
        pthread_create(&tid,NULL,&jieshou,(void*)&ms);
        
    }

    close(socket_fd);
    close(socket_ok);
    return 0;
}

more_one_client.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>


//多个客户端通信和服务端单向通信
//客户端程序
int socket_fd = -1;

void* jieshou(void* arg){

    char msg[128];
    while(1){
        memset(msg,0,sizeof(msg));
        //5.接收消息
        recv(socket_fd,msg,sizeof(msg),0);//阻塞等待
        printf("客户端接收到:%s",msg);

        //退出
        if(strcmp("bye\n",msg)==0){
            break;
        }
    }
}


int main(int argc,char** argv)
{
    //1.创建待连接套接字
    socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2.绑定套接字与网络地址
    //第二个参数需要这个结构体
    struct sockaddr_in s_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[2]));//设置端口//主机字节序的短整型数据
    s_addr.sin_addr.s_addr = inet_addr(argv[1]);//将点分十进制转为无符号的32位网络地址

    int bind_ok = bind(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    if(bind_ok==-1){
        perror("bind failed");
    }


    //3.请求连接
    connect(socket_fd,(struct sockaddr*)&s_addr,sizeof(s_addr));
    

    //开始畅聊吧
    //创建线程
    pthread_t tid;
    pthread_create(&tid,NULL,&jieshou,NULL);

    char buf[128];
    while(1){

        memset(buf,0,sizeof(buf));

        fgets(buf,sizeof(buf),stdin);//从键盘获取输入
        //发送消息
        send(socket_fd,buf,sizeof(buf),0);
        printf("客户端发送:%s",buf);

        //退出
        if(strcmp("bye\n",buf)==0){
            break;
        }
    }

    close(socket_fd);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1291688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据分析基础之《matplotlib(3)—散点图》

一、常见图形种类及意义 1、matplotlib能够绘制折线图、散点图、柱状图、直方图、饼图。我们需要知道不同的统计图的意义&#xff0c;以此来决定选择哪种统计图来呈现我们的数据 2、折线图plot 说明&#xff1a;以折线的上升或下降来表示统计数量的增减变化的统计图 特点&…

Python实现FA萤火虫优化算法优化随机森林分类模型(RandomForestClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法&#xff08;Fire-fly algorithm&#xff0c;FA&#xff09;由剑桥大学Yang于2009年提出 , …

pandas数据转换成ndarray数组

Pandas 和 NumPy 被认为是科学计算与机器学习中必不可少的库&#xff0c;因为它们具有直观的语法和高性能的矩阵计算能力。下面对 Pandas 与 NumPy 进行简单的总结&#xff0c;如下表所示&#xff1a; 要将Pandas DataFrame转换为ndarray数组&#xff0c;您可以使用.values属…

统计centos系统哪一个进程打开文件描述符

一&#xff1a;找出前10进程打开的描述符 # find /proc/ -print|grep -P /proc/\d/fd|awk -F/ {print $3}|uniq -c|sort -rn |awk {print "进程 "$2" 打开 "$1" 个文件描述符"}|head 二&#xff1a;通过进程id找出对应的进程运行的程序。 # ps…

tensorflow模型的加载及保存,以及在C++端的部署

一、模型保存和加载 参考文章:TensorFlow2.0 —— 模型保存与加载 方法一、 仅保存模型权重(model.save_weights) 有两种保存模型权重的方法,一种是保存.h5形式。model.save_weights("adasd.h5") # 模型权重保存 model.load_weights("adasd.h5") # 模型…

外贸新人警惕:做外贸要注意的6个风险

近期外贸新人非常多&#xff0c;在这里给大家安利一波出口业务的注意事项。 一般情况下&#xff0c;风险主要有以下六种情况&#xff1a; 1、出货规格、日期与合同规定不符造成的收汇分险 出口方未按合同或信用证规定交货。 一是生产误工&#xff0c;造成晚交货&#xff1b; …

深入理解数据在内存中是如何存储的,位移操作符如何使用(能看懂文字就能明白系列)文章超长,慢慢品尝

系列文章目录 C语言笔记专栏 能看懂文字就能明白系列 &#x1f31f; 个人主页&#xff1a;古德猫宁- &#x1f308; 信念如阳光&#xff0c;照亮前行的每一步 文章目录 系列文章目录&#x1f308; *信念如阳光&#xff0c;照亮前行的每一步* 前言引子一、2进制和进制转化为什么…

洗鞋机行业分析:2023年市场发展前景及消费现状

随着消费主力的转移&#xff0c;年轻群体在消费中的话语权和影响力越来越大&#xff0c;“精致懒”正在成为潮流。洗鞋机作为消费升级时代的产物&#xff0c;自诞生以来&#xff0c;经过十几年的发展&#xff0c;逐渐被年轻消费者熟知&#xff0c;洗鞋机品牌阵营和产品种类也变…

做外贸和你想的不一样

半夜突然想起来以前刚毕业入职的时候&#xff0c;那会在网上投简历基本上都是招聘外贸业务员的&#xff0c;可能那个时段正是外贸的高潮期&#xff0c;阿里那会还可以免费注册&#xff0c;免费试用开发客户。 然后我们同学们结队的一起去找工作&#xff0c;一般是有一个同学收…

万兆单模OSX010000:企业高速网络传输可靠解决方案

随着信息技术的不断发展&#xff0c;企业对于高速网络传输的需求不断增加。网络设备需要不断更新换代&#xff0c;以满足更高速、更远距离的传输要求。万兆单模光模块OSX010000是华为旗下的基于光纤传输的万兆单模光模块&#xff0c;适用于长距离的数据传输。本文将介绍什么是万…

python获取js data.now同款时间戳

import requestsimport time from datetime import datetimecu_t datetime.now() se cu_t.timestamp()*1000 se int(se) print(se)#cur_time time.time()*1000 #seconds int(cur_time) #print(seconds)

矩阵处理—旋转正方形矩阵

与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 旋转正方形矩阵1 题目描述2 解决思路3 代码实现 &#x1f48e;总结 旋转正方形矩阵 1 题目描述 有一个n*n的矩阵&#xff0c;现在把整个矩阵顺时针旋转90&#xff0c;如图&#xff1a; 2 解决思路 设置四个指针&…

2023人工智能和市场营销的融合报告:创造性合作的新时代需要新的原则

今天分享的人工智能系列深度研究报告&#xff1a;《2023人工智能和市场营销的融合报告&#xff1a;创造性合作的新时代需要新的原则》。 &#xff08;报告出品方&#xff1a;M&CSAATCHITHINKS&#xff09; 报告共计&#xff1a;11页 生成型人工智能的兴起和重要性 生成式…

vue的data

类型&#xff1a;Object | Function 限制&#xff1a;组件的定义只接受 function。 详细&#xff1a; Vue 实例的数据对象。Vue 会递归地把 data 的 property 转换为 getter/setter&#xff0c;从而让 data 的 property 能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个…

localhost工具:本地代码的远程之路 | 京东云技术团队

在日常的开发过程中&#xff0c;本地代码远程调试一直是最理想的开发状态。本文通过介绍京东集团内开发的一个轻量简单的小工具”localhost”&#xff0c;从多角度的方案思考&#xff0c;到原理介绍&#xff0c;到最终的方案落地&#xff0c;在开发阶段发现问题&#xff0c;解决…

短视频账号剪辑矩阵+无人直播系统源头开发

抖去推爆款视频生成器&#xff0c;通过短视频矩阵、无人直播&#xff0c;文案引流等&#xff0c;打造实体商家员工矩阵、用户矩阵、直播矩阵&#xff0c;辅助商家品牌曝光&#xff0c;团购转化等多功能赋能商家拓客引流。 短视频矩阵通俗来讲就是批量剪辑视频和批量发布视频&am…

洗眼镜机怎样?清洗机什么牌子好质量过硬、爆款超声波清洗机排名

戴眼镜的朋友真的可以试试超声波清洗机&#xff0c;家里备着一个超声波清洗机&#xff0c;即使是眼镜脏了也不用再麻烦的跑去眼镜店清洗了&#xff01;由于目前市面上超声波清洗机的品牌实在太多&#xff0c;让想要体验超声波清洗机的朋友挑花了眼也找不到一款合适的&#xff0…

Centos7如何配置firewalld防火墙规则

博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码下载地址&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb;…

每日一题 1466. 重新规划路线(树,DFS)

根据 connections 建立无向树从 0 开始深搜&#xff0c;每次调用 dfs 时判断路径方向是否正确 class Solution:def minReorder(self, n: int, connections: List[List[int]]) -> int:to defaultdict(set)edge defaultdict(list)for con in connections:edge[con[0]].appe…

JS实现网页页面的框架(demo)

采用JS实现网页页面的框架 采用的技术点有html&#xff0c;css&#xff0c;JS&#xff0c;jQuery 成品&#xff1a; HTML&#xff1a; <html><head><meta charset"utf-8"><title></title><link rel"stylesheet" href&…