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

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

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

相关文章

Docker快速理解及简介

docker快速理解及简介 1.Docker为什么出现&#xff1f; 迁移一个项目时&#xff0c;运行文档、配置环境、运行环境、运行依赖包、操作系统发行版、内核等都需要重新安装配置&#xff0c;比较麻烦。 2.Docker是什么&#xff1f; Docker是基于Go语言实现的云开源项目。解决了运行…

C语言指针详解上

1 野指针 int main01(){//野指针就是没有初始化的指针,指针的指向是随机的,不可以 操作野指针//int a 0;//指针p保存的地址一定是定义过的(向系统申请过的)int *p;//野指针*p 200;printf("%d\n",*p);system("pause");return 0;}2 空指针 空指针的作用…

手把手将Visual Studio Code变成Python开发神器

Visual Studio Code 是一款功能强大、可扩展且轻量级的代码编辑器&#xff0c;经过多年的发展&#xff0c;已经成为 Python 社区的首选代码编辑器之一 下面我们将学习如何安装 Visual Studio Code 并将其设置为 Python 开发工具&#xff0c;以及如何使用 VS Code 提高编程工作…

在 Windows 桌面的redis中远程连接到 VMware 中运行的 Linux 上的 Redis

先修改一下docker容器中的redis(一会连上之后看效果) 我使用的是VMware的虚拟机 选择的网络设置为桥接模式 查到虚拟机独立的ip是如下 允许 Linux 虚拟机上的 Redis 监听外部连接&#xff1a; 打开 Linux 虚拟机上的 Redis 配置文件。在大多数系统上&#xff0c;配置文件位于…

编程应用实例,养生馆会员管理系统软件统计查询教程

一、前言 编程应用实例&#xff0c;养生馆会员管理系统软件&#xff0c; 导航栏菜单有 系统设置&#xff1a;可以设置操作员的权限以及打印机参数设置。 会员信息登记&#xff1a;可以直接用手机号登记电子会员卡 会员卡充值&#xff1a;可以直接报手机号充值&#xff0c;…

AntDB数据库助力中国移动结算中心建设

结算中心负责中国移动漫游伙伴进行数据和财务清算支撑。本次结算中心项目涉及结算处理、资料管理、信息管理等模块&#xff0c;用以构建系统的结算能力。 建设需求 结算中心现有传统集中式架构的数据库无法做到根据业务量变化进行弹性扩缩容&#xff0c;目前系统数据量巨大&a…

ESP32-Web-Server编程- 在 Web 上开发动态纪念册

ESP32-Web-Server编程- 在 Web 上开发动态纪念册 概述 Web 有很多有趣的玩法&#xff0c;在打开网页的同时送她一个惊喜。 需求及功能解析 本节演示在 ESP32 上部署一个 Web&#xff0c;当打开对应的网页时&#xff0c;将运行动态的网页内容&#xff0c;显示炫酷的纪念贺词…

计算机操作系统4

1.什么是进程同步 2.什么是进程互斥 3.进程互斥的实现方法(软件) 4.进程互斥的实现方法(硬件) 5.遵循原则 6.总结&#xff1a; 线程是一个基本的cpu执行单元&#xff0c;也是程序执行流的最小单位。 调度算法&#xff1a;先来先服务FCFS、短作业优先、高响应比优先、时间片…

有趣的代码——有故事背景的程序设计5

接着上篇文章再和大家分享一下有趣的代码&#xff01; 目录 1.求母串中子串的个数 2.行走机器人 3.荷兰国旗问题 4.统计考研成绩 1.求母串中子串的个数 给定一个母串s和一个子串t&#xff0c;在主串s中寻找子串t的过程为字符串匹配。每匹配成功一次&#xff0c;即母串中含有…

移动app测试要不要做第三方软件测试?

移动app测试是指通过对移动应用进行全面的评估和验证&#xff0c;以确保其功能和性能符合设计要求&#xff0c;以提供给用户最好的体验。通常包括功能测试、界面测试、性能测试、兼容性测试等多个环节。由于现在越来越多的软件企业会选择将测试工作交由第三方软件测试进行&…

【Git】本地代码如何托管到远程仓库(保姆级教程)

注意前提是你本地已经安装了Git 1. 新建远程仓库 选一个git服务器&#xff0c;新建一个远程仓库&#xff0c;这里我选用的是gitee 点击确定后&#xff0c;显示如下界面表示仓库已经新建完成 2.建立本地仓库 本地新建一个空文件夹&#xff0c;在里面写一些你的初始代码文件。…

夜莺专业版网络设备功能介绍

网络设备采集简介 网络设备的问题通常会产生较大范围的影响&#xff0c;因此采集监控网络设备是一项常见的任务。不同公司在实施网络设备采集时可能采用不同的方案&#xff0c;主要有三类&#xff1a; SNMP&#xff08;Simple Network Management Protocol&#xff09;&#x…

2个月拿下信息系统项目管理师攻略(攻略超级全)

信息系统项目管理师&#xff08;高项&#xff09;一次性过啦&#xff01;结合这次备考经验&#xff0c;给大家总结一下复习方法。 先上图&#xff0c;开心一下&#xff01; 一、我为什么选择了高项 为什么我会选信息系统项目管理师&#xff0c;也就是我们常说的高项。 原因1…

深入浅出分析kafka客户端程序设计 ----- 生产者篇----万字总结

前面在深入理解kafka中提到的只是理论上的设计原理&#xff0c; 本篇讲得是基于c语言的kafka库的程序编写&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 首先要编写生产者的代码&#xff0c;得先知道生产者的逻辑在代码上是怎么体现的 1.kafka生产者的逻辑 …

zookeeper集群 +kafka集群

1.zookeeper kafka3.0之前依赖于zookeeper zookeeper是一个开源&#xff0c;分布式的架构&#xff0c;提供协调服务&#xff08;Apache项目&#xff09; 基于观察者模式涉及的分布式服务管理架构 存储和管理数据&#xff0c;分布式节点上的服务接受观察者的注册&#xff0c…

ubuntu18.04 vscode 安装 vue.volar Vue Language Features (Volar) , vue3 必备插件

直接在vscode 里面下载老是失败&#xff0c;不是网络问题&#xff0c;而是vue.volar插件配置的vscode版本与vscode版本不一致导致出现安装失败 官网下载最新的 vue.volar插件 https://marketplace.visualstudio.com/ 官网搜索 vue.volar 然后打开 Vue Language Features (Vol…

类和对象,this指针

一、类的引入&#xff1a; 如下&#xff0c;在C中&#xff0c;我们可以在结构体中定义函数&#xff0c;如下&#xff0c;之前我们学习C中中一直是在结构体中定义变量。 struct student{void studentinfo(const char* name,const char* gener,int age){ strcpy(_name,name);st…

一个类似connectedpapers的文献知识图谱神器:Libraries S2

在阅读文献、写综述、写论文的related works的时候&#xff0c;总会苦恼如何查阅该领域的论文呢&#xff1f;怎么才能尽可能的查找齐全&#xff1f; 以前在看论文的时候&#xff0c;我都是先用谷歌学术搜索&#xff0c;然后看到优秀的相关文文献后&#xff0c;再去查看它的参考…

java应用在Windows服务器运行时控制台输出日志中文乱码终极解决办法

修改注册表&#xff0c;适用于cmd&#xff0c;在各种开发工具终端中均生效 第一步、按winr&#xff0c;输入regedit运行&#xff0c;进入注册表界面 第二步、找到【HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor】 第三步、新建一个表项&#xff0c;命名为autor…

世微 AP3266 大功率同步降压恒流芯片 过EMC 车灯驱动

产品描述 AP3266 是高效率、外围简单、内置功率管的同步降压恒流芯片&#xff0c;适用于4-40V输入的降压LED恒流驱动芯片。输出最大功率可达 40W&#xff0c;最大电流3.6A。AP3266 可通过调节 OVP 端口的分压电阻&#xff0c;设定输出空载电压 保护&#xff0c;避免高压 空载上…