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

前言

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

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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java ThreadLocal 实现原理 与 如何使用弱引用解决内存泄漏问题

目录 一、ThreadLocal 有什么用二、ThreadLocal 使用示例三、ThreadLocal 实现原理四、ThreadLocal 如何是使用弱引用解决内存泄漏问题4.1、强引用内存泄漏分析4.1、弱引用解决内存泄漏问题 一、ThreadLocal 有什么用 ThreadLocal 诞生于 JDK 1.2&#xff0c;用于解决多线程间的…

基于ssm学院党员管理系统论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对鄂尔多斯应用技术学院党员信息管理混乱&#xff0c;出错率高&#x…

javaWebssh图书系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

系统前景 图书有很多&#xff0c;老的图书书的管理靠纸介质&#xff0c;浪费人力和物力&#xff0c;给图书管理者带来极大的资源浪费。随着计算机信息化的普及&#xff0c;对图书的管理带来本质的改变&#xff0c;图书的销售情况以及&#xff0c;图书管理&#xff0c;以及年终对…

振弦采集仪助力岩土工程质量控制

振弦采集仪助力岩土工程质量控制 随着工程建设规模越来越大&#xff0c;建筑结构的安全性和稳定性越来越成为人们所关注的焦点。岩土工程在工程建设中占据着非常重要的地位&#xff0c;岩土工程质量控制更是至关重要。而振弦采集仪作为一种先进的检测设备&#xff0c;正得到越…

Linux命令之ps

Linux命令之ps ps命令的基本用法**常用的ps命令示例** ps命令的基本用法 ps: 显示当前终端会话中属于当前用户的进程列表。 ps -ef: 显示系统中所有进程的列表&#xff0c;包括其他用户的进程。 ps -aux: 显示详细的进程信息&#xff0c;包括CPU和内存使用情况等。 -e选项&…

浅谈如何写开发信和报价?外贸邮件怎么写?

外贸开发信要写报价进去吗&#xff1f;写开发信能加产品价格吗&#xff1f; 开发信和报价是连接您和潜在客户之间的纽带&#xff0c;它们有助于传达您的价值主张、产品或服务的优势以及价格细节。蜂邮EDM将探讨如何撰写令人印象深刻的开发信和报价&#xff0c;以吸引更多的潜在…

AIGC:使用变分自编码器VAE实现MINIST手写数字生成

1 变分自编码器介绍 变分自编码器&#xff08;Variational Autoencoders&#xff0c;VAE&#xff09;是一种生成模型&#xff0c;用于学习数据的分布并生成与输入数据相似的新样本。它是一种自编码器&#xff08;Autoencoder&#xff09;的扩展&#xff0c;自编码器是一种用于…

严蔚敏数据结构p17(2.19)——p18(2.24) (c语言代码实现)

目录 2.19已知线性表中的元素以值递增有序排列,并以单链表作存储结构。试写一高效的算法,删除表中所有值大于 mink 且小于 maxk 的元素(若表中存在这样的元素&#xff09;同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink 和 maxk 是给定的个参变量,它们的值可以和表…

【JavaEE】生产者消费者模式

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

从零开始学习 JS APL(一):完整指南和实例解析

本章内容主要是按一下来&#xff1a; 操作DOM BOM 比如 控制网页元 素交互等各种网页 交互效果 以下是我总结笔记&#xff08;仅供参考&#xff09; webAPL 获取DOM对象 变量声明有三个 var let 和 const 我们应该用那个呢&#xff1f; 首先var 先排除&#xff0c;老派写法…

UDP协议实现群聊

代码&#xff1a; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.IOException; import java.lang.String; public class liaotian extends JFrame{ private static final int DEFAULT_PORT8899; private J…

机器的深度强化学习算法可以被诱导

设计一个好的奖励函数是机器深度强化学习算法的关键之一。奖励函数用于给予智能体&#xff08;机器&#xff09;在环境中采取不同行动时的反馈信号&#xff0c;以指导其学习过程。一个好的奖励函数应该能够引导智能体朝着期望的行为方向学习&#xff0c;并尽量避免潜在的问题&a…

使用ASIRequest库进行Objective-C网络爬虫示例

在Objective-C中&#xff0c;ASIHTTPRequest是一个非常受欢迎的库&#xff0c;用于处理HTTP请求。它可用于下载网页内容&#xff0c;处理API请求&#xff0c;甚至进行复杂的网络交互。下面是一个简单的示例&#xff0c;展示了如何使用ASIHTTPRequest库来爬取网页代码。 首先&a…

【ROS2指南-9】Bag的record和play操作

目标&#xff1a;记录在某个话题上发布的数据&#xff0c;以便您可以随时回放和检查它。 教程级别&#xff1a;初学者 时间&#xff1a; 10分钟 内容 背景 先决条件 任务 1 设置 2 选择一个主题 3 ros2包记录 4 ros2 包信息 5 ros2包玩 概括 下一步 相关内容 背景 …

Java 简易版 TCP UDP聊天

客户端 import java.io.*; import java.net.Socket; import java.util.Date; import javax.swing.*;public class MyClient {private JFrame jf;private JButton jBsend;private JTextArea jTAcontent;private JTextField jText;private JLabel JLcontent;private Date data;pr…

自定义类加载器

通过继承ClassLoader类&#xff0c;重写findClass方法&#xff0c;实现自定义类加载器。 一、自定义类加载器 package com.molange.JavaSE.myclassloader;import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; impor…

MATLAB - 绘制立体图(平面+水深)

目录 代码结果 代码 % 在 X-Y 平面上绘图 % 正常绘制平面图 [X,Y,Z] peaks; contour(X,Y,Z,20); hold on% ****重点******************************************** % 改为三维视图&#xff0c;具体可以help % view(3); %此时的平面图对应z0 &#xff1b;默认az-37.5&#x…

大模型在企业知识库场景的落地思考

一、引言 在这个信息爆炸的时代&#xff0c;企业的知识库已不再是简单的数据堆砌&#xff0c;而是需要智能化、高效率的知识管理和利用。大模型作为AI领域的一个重要突破&#xff0c;正逐步成为企业知识库管理的强大助力。通过前面一段时间对于大模型在企业落地的深入调研和实…

Linux---逻辑卷管理

本章主要介绍逻辑卷的管理。 了解什么是逻辑卷创建和删除逻辑卷扩展逻辑卷缩小逻辑卷逻辑卷快照的使用 前面介绍了分区的使用&#xff0c;如果某个分区空间不够&#xff0c;想增加空间是非常困难的。所以&#xff0c;建议尽可能使用逻辑卷而非普通的分区&#xff0c;因为逻辑卷…

【C语言】数据在内存中的存储

目录 练笔 整型数据的存储&#xff1a; char 型数据——最简单的整型 整型提升&#xff1a; 推广到其他整形&#xff1a; 大小端&#xff1a; 浮点型数据的存储&#xff1a; 存储格式&#xff1a; 本篇详细介绍 整型数据&#xff0c;浮点型数据 在计算机中是如何储存的。…