C语言项目实战FTP文件传输(windows网络编程基础)

文章目录

  • 前言
  • 一、客户端和服务端介绍
  • 二、客户端和服务器之间进行通信的过程
      • 客户端和服务器建立通信的流程
      • 通信过程的示例图
      • 流程说明
  • 三、客户端代码编写
      • 代码解释
  • 四、服务端代码编写
      • 代码解释
  • 总结


前言

本篇文章开始将带大家来学习FTP文件传输助手的项目实现,这个项目的实现会包含网络编程中的内容和学习,希望通过这套文章可以带大家完成这样的一个项目。

一、客户端和服务端介绍

在Windows中进行网络编程,客户端和服务端的实现主要依赖于Windows Socket(Winsock)API。以下是对Windows中网络编程的客户端和服务端的详细介绍,包括关键功能、常用技术和示例代码。

客户端
功能
用户交互

提供界面供用户输入服务器地址、端口和消息。
接收用户输入,并将请求发送到服务端。
网络通信

建立与服务端的连接,发送请求并接收响应。
处理数据传输中的各种情况,如连接超时、数据丢失等。
数据处理

对接收到的数据进行处理和展示。
例如,显示服务端返回的响应信息。
技术架构
Winsock API

使用Windows提供的Winsock API进行网络编程。
包括函数如socket(), connect(), send(), recv(), closesocket()等。
网络协议

支持多种网络协议,最常用的是TCP和UDP。
TCP用于可靠的点对点连接,UDP用于快速的无连接通信。

服务端
功能
连接管理

监听特定端口,接受客户端连接请求。
管理多个客户端连接,处理并发请求。
请求处理

接收客户端请求,进行相应的处理。
例如,返回特定数据或执行某些操作。
数据传输

发送和接收数据,确保通信的正确性和可靠性。
处理数据传输中的错误和异常情况。

二、客户端和服务器之间进行通信的过程

客户端和服务器建立通信的流程

建立客户端和服务器之间的通信通常包括以下几个步骤:

  1. 初始化

    • 客户端和服务器都需要初始化网络库。例如,在Windows系统中,这通常涉及调用 WSAStartup() 来初始化 Winsock 库。
  2. 创建套接字

    • 客户端服务器都需要创建一个网络套接字。这个套接字是进行网络通信的基础。套接字的创建过程涉及指定协议族(如IPv4)、套接字类型(如流式套接字用于TCP)和协议。
  3. 绑定(仅服务器端)

    • 服务器端需要将套接字绑定到本地的IP地址和端口号。这一步骤确定了服务器将监听哪个端口上的连接请求。
  4. 监听(仅服务器端)

    • 服务器端将套接字设置为监听状态,等待客户端的连接请求。这是通过 listen() 函数实现的。
  5. 连接(仅客户端)

    • 客户端使用 connect() 函数尝试连接到服务器端。客户端需要知道服务器的IP地址和端口号。
  6. 接受连接(仅服务器端)

    • 服务器端接受客户端的连接请求。这是通过 accept() 函数实现的,一旦连接建立,服务器和客户端可以开始数据交换。
  7. 数据交换

    • 客户端服务器端可以通过套接字发送和接收数据。这是通过 send()recv() 函数完成的。
  8. 关闭连接

    • 当数据交换完成后,客户端服务器端都可以关闭套接字,释放相关资源。这是通过 closesocket() 函数完成的。

通信过程的示例图

以下是一个简化的通信过程示意图,展示了客户端和服务器之间的基本交互:

客户端 (Client)                   服务器 (Server)
-----------------                   -----------------|                                      || (1) 初始化网络库                    ||----------------->                   ||                                      || (2) 创建套接字                       ||----------------->                   ||                                      || (3) 连接到服务器                   ||----------------->                   ||                                      ||                       (4) 初始化网络库||                                      ||                       (5) 创建套接字 ||                                      ||                       (6) 绑定套接字 ||                                      ||                       (7) 监听连接   ||                                      ||                                      |<---- (8) 监听连接|                                      || (9) 接受连接                         ||<-----------------                   ||                                      || (10) 数据交换                       ||<----------------->                   ||                                      || (11) 关闭连接                       ||----------------->                   ||                                      ||                                      ||                                      |<---- (12) 关闭连接

流程说明

  1. 客户端服务器端初始化网络库。
  2. 客户端服务器端创建网络套接字。
  3. 客户端连接到服务器端
  4. 服务器端初始化网络库(如果还没初始化)。
  5. 服务器端创建网络套接字。
  6. 服务器端将套接字绑定到本地的IP地址和端口号。
  7. 服务器端设置套接字为监听状态,等待客户端连接。
  8. 服务器端监听来自客户端的连接请求。
  9. 客户端发起连接请求,服务器端接受连接。
  10. 客户端服务器端进行数据交换。
  11. 客户端关闭连接。
  12. 服务器端关闭连接。

这个流程和示意图描述了一个基本的网络通信过程,其中客户端和服务器之间的每个步骤都很关键,以确保数据的正确传输和连接的管理。

三、客户端代码编写

这里会使用到网络调试助手来充当服务器,等待接收到客户端的连接。

在这里插入图片描述

程序代码:

下面是一个简化的Windows网络编程中的客户端代码示例,使用C语言编写。这个客户端连接到服务器,发送一条消息,然后接收服务器的响应。代码中包含详细注释以帮助理解每个步骤。

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库#define SERVER_ADDRESS "127.0.0.1" // 服务器IP地址
#define SERVER_PORT 8080           // 服务器端口号void error_exit(const char *message) {fprintf(stderr, "Error: %s. Error code: %d\n", message, WSAGetLastError());WSACleanup();exit(EXIT_FAILURE);
}int main() {WSADATA wsaData;SOCKET sock;struct sockaddr_in server;char message[] = "Hello, Server!";char buffer[512];int bytesReceived;// 1. 初始化 Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {error_exit("Failed to initialize Winsock");}// 2. 创建套接字sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock == INVALID_SOCKET) {error_exit("Failed to create socket");}// 3. 配置服务器地址结构server.sin_family = AF_INET;server.sin_port = htons(SERVER_PORT);server.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);// 4. 连接到服务器if (connect(sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {error_exit("Failed to connect to server");}// 5. 发送数据if (send(sock, message, sizeof(message), 0) == SOCKET_ERROR) {error_exit("Failed to send data");}// 6. 接收数据bytesReceived = recv(sock, buffer, sizeof(buffer) - 1, 0);if (bytesReceived == SOCKET_ERROR) {error_exit("Failed to receive data");}// 7. 确保接收到的数据是以空字符结束的buffer[bytesReceived] = '\0';// 8. 打印接收到的消息printf("Received from server: %s\n", buffer);// 9. 关闭套接字closesocket(sock);// 10. 清理 WinsockWSACleanup();return 0;
}

代码解释

  1. 初始化 Winsock

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {error_exit("Failed to initialize Winsock");
    }
    
    • 使用 WSAStartup() 初始化 Winsock 库,以便使用网络功能。
  2. 创建套接字

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET) {error_exit("Failed to create socket");
    }
    
    • 使用 socket() 创建一个TCP套接字,AF_INET 表示IPv4,SOCK_STREAM 表示流式套接字(TCP),IPPROTO_TCP 表示使用TCP协议。
  3. 配置服务器地址结构

    server.sin_family = AF_INET;
    server.sin_port = htons(SERVER_PORT);
    server.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);
    
    • 设置服务器的地址、端口号和IP地址。
  4. 连接到服务器

    if (connect(sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {error_exit("Failed to connect to server");
    }
    
    • 使用 connect() 函数连接到服务器。如果连接失败,打印错误信息并退出程序。
  5. 发送数据

    if (send(sock, message, sizeof(message), 0) == SOCKET_ERROR) {error_exit("Failed to send data");
    }
    
    • 使用 send() 函数将数据发送到服务器。如果发送失败,打印错误信息并退出程序。
  6. 接收数据

    bytesReceived = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (bytesReceived == SOCKET_ERROR) {error_exit("Failed to receive data");
    }
    
    • 使用 recv() 函数接收从服务器返回的数据。如果接收失败,打印错误信息并退出程序。
  7. 确保接收到的数据是以空字符结束的

    buffer[bytesReceived] = '\0';
    
    • 在接收到的数据末尾添加空字符,以确保它是一个有效的字符串。
  8. 打印接收到的消息

    printf("Received from server: %s\n", buffer);
    
    • 打印从服务器接收到的消息。
  9. 关闭套接字

    closesocket(sock);
    
    • 使用 closesocket() 关闭套接字,释放资源。
  10. 清理 Winsock

    WSACleanup();
    
    • 使用 WSACleanup() 清理 Winsock 库,完成网络编程的清理工作。

这个示例展示了如何在Windows平台上创建一个简单的客户端应用程序,与服务器进行通信。代码中的每个步骤都包括详细的注释,帮助理解网络编程中的基本操作。

调试结果:
在这里插入图片描述

四、服务端代码编写

下面是一个简单的Windows服务端代码示例,使用C语言编写。这个服务端程序会监听特定端口,接收来自客户端的消息,并发送一个响应消息。代码中包含详细注释以帮助理解每个步骤。

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库#define SERVER_PORT 8080 // 服务器端口号
#define BUFFER_SIZE 512 // 缓冲区大小void error_exit(const char *message) {fprintf(stderr, "Error: %s. Error code: %d\n", message, WSAGetLastError());WSACleanup();exit(EXIT_FAILURE);
}int main() {WSADATA wsaData;SOCKET serverSocket, clientSocket;struct sockaddr_in server, client;int clientSize = sizeof(client);char buffer[BUFFER_SIZE];int bytesReceived;// 1. 初始化 Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {error_exit("Failed to initialize Winsock");}// 2. 创建套接字serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (serverSocket == INVALID_SOCKET) {error_exit("Failed to create socket");}// 3. 配置服务器地址结构server.sin_family = AF_INET;server.sin_addr.s_addr = INADDR_ANY; // 监听所有网络接口server.sin_port = htons(SERVER_PORT);// 4. 绑定套接字到端口if (bind(serverSocket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {error_exit("Failed to bind socket");}// 5. 监听传入连接if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {error_exit("Failed to listen on socket");}printf("Waiting for a connection...\n");// 6. 接受客户端连接clientSocket = accept(serverSocket, (struct sockaddr*)&client, &clientSize);if (clientSocket == INVALID_SOCKET) {error_exit("Failed to accept client connection");}printf("Client connected.\n");// 7. 接收数据bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE - 1, 0);if (bytesReceived == SOCKET_ERROR) {error_exit("Failed to receive data");}// 8. 确保接收到的数据是以空字符结束的buffer[bytesReceived] = '\0';// 9. 打印接收到的消息printf("Received from client: %s\n", buffer);// 10. 发送响应数据const char *response = "Hello, Client!";if (send(clientSocket, response, strlen(response), 0) == SOCKET_ERROR) {error_exit("Failed to send data");}// 11. 关闭客户端套接字closesocket(clientSocket);// 12. 关闭服务器套接字closesocket(serverSocket);// 13. 清理 WinsockWSACleanup();return 0;
}

代码解释

  1. 初始化 Winsock

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {error_exit("Failed to initialize Winsock");
    }
    
    • 使用 WSAStartup() 初始化 Winsock 库,以便使用网络功能。
  2. 创建套接字

    serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (serverSocket == INVALID_SOCKET) {error_exit("Failed to create socket");
    }
    
    • 使用 socket() 创建一个TCP套接字,AF_INET 表示IPv4,SOCK_STREAM 表示流式套接字(TCP),IPPROTO_TCP 表示使用TCP协议。
  3. 配置服务器地址结构

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY; // 监听所有网络接口
    server.sin_port = htons(SERVER_PORT);
    
    • 设置服务器的地址、端口号,并指定 INADDR_ANY 以监听所有网络接口。
  4. 绑定套接字到端口

    if (bind(serverSocket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {error_exit("Failed to bind socket");
    }
    
    • 使用 bind() 将套接字绑定到指定的IP地址和端口。如果绑定失败,打印错误信息并退出程序。
  5. 监听传入连接

    if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {error_exit("Failed to listen on socket");
    }
    
    • 使用 listen() 函数开始监听传入的连接请求。SOMAXCONN 表示允许的最大连接请求队列长度。
  6. 接受客户端连接

    clientSocket = accept(serverSocket, (struct sockaddr*)&client, &clientSize);
    if (clientSocket == INVALID_SOCKET) {error_exit("Failed to accept client connection");
    }
    
    • 使用 accept() 函数接受来自客户端的连接请求。clientSocket 是与客户端通信的套接字。
  7. 接收数据

    bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE - 1, 0);
    if (bytesReceived == SOCKET_ERROR) {error_exit("Failed to receive data");
    }
    
    • 使用 recv() 函数接收来自客户端的数据。如果接收失败,打印错误信息并退出程序。
  8. 确保接收到的数据是以空字符结束的

    buffer[bytesReceived] = '\0';
    
    • 在接收到的数据末尾添加空字符,以确保它是一个有效的字符串。
  9. 打印接收到的消息

    printf("Received from client: %s\n", buffer);
    
    • 打印从客户端接收到的消息。
  10. 发送响应数据

    const char *response = "Hello, Client!";
    if (send(clientSocket, response, strlen(response), 0) == SOCKET_ERROR) {error_exit("Failed to send data");
    }
    
    • 使用 send() 函数向客户端发送响应数据。如果发送失败,打印错误信息并退出程序.
  11. 关闭客户端套接字

    closesocket(clientSocket);
    
    • 使用 closesocket() 关闭与客户端的连接。
  12. 关闭服务器套接字

    closesocket(serverSocket);
    
    • 使用 closesocket() 关闭服务器套接字,释放资源。
  13. 清理 Winsock

    WSACleanup();
    
    • 使用 WSACleanup() 清理 Winsock 库,完成网络编程的清理工作。

运行结果:

在这里插入图片描述

总结

本篇文章就讲解到这里,在学习网络编程的时候大家需要先将基础知识掌握牢固再进行编程训练。

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

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

相关文章

【单片机毕业设计选题24099】-室内空气质量检测及净化系统

系统功能: 系统上电后OLED显示“欢迎使用请稍后”两秒后进入正常界面显示&#xff0c; 第一行显示温湿度和MQ2值 第二行显示采集到的甲醛值 第三行显示采集到的PM2.5值 第四行显示设定的PM2.5值 短按B4按键增加PM2.5设定阈值 短按B5按键减小PM2.5设定阈值 如果PM2.5采集…

达梦数据库dsc集群动态添加节点

前提条件&#xff1a;在安装好的的dsc集群&#xff1a;达梦数据库dsc集群保姆级部署文档_达梦数据库文档-CSDN博客上动态添加节点 1、环境信息 扩展节点信息&#xff1a; 操作环境&#xff1a;VMware Workstation 16 Pro dmdsc集群 机器ip 主机名 操作系统 资源配置 实…

【传知代码】基于标签相关性的多标签学习(论文复现)

在当今信息爆炸的时代&#xff0c;数据中包含的标签信息对于理解和分析复杂问题至关重要。在诸如文本分类、图像识别和推荐系统等应用中&#xff0c;如何有效地利用标签相关性提升多标签学习的效果成为了研究的热点之一。基于标签相关性的多标签学习方法&#xff0c;通过挖掘不…

JAVA项目基于SpringBoot的外卖点餐管理系统

目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着生活节…

Flink笔记整理(六)

Flink笔记整理&#xff08;六&#xff09; 完整系列在公众号&#xff1a;是十三不是四十三&#xff0c;欢迎关注~ 文章目录 Flink笔记整理&#xff08;六&#xff09;八、状态管理8.1 Flink中的状态概述状态的分类 8.2 按键分区状态&#xff08;Keyed State&#xff09;值状态…

Windows 添加自定义服务实现开机(用户登录之前)自动运行 Python 脚本

实现效果 使用 Python 编写的一个脚本, 希望在 Windows 系统启动时, 用户登录之前就自动运行. 准备工作 首先确保 Python 脚本可以手动正常运行, 演示起见, 编写下面的一个简单的脚本用于在 C 盘根目录中生成一个包含脚本运行时间戳的文本文件. Python 脚本存放在 C:\Python…

python爬虫实践

两个python程序的小实验&#xff08;附带源码&#xff09; 题目1 爬取http://www.gaosan.com/gaokao/196075.html 中国大学排名&#xff0c;并输出。提示&#xff1a;使用requests库获取页面的基本操作获取该页面&#xff0c;运用BeautifulSoup解析该页面绑定对象soup&#x…

搭建jenkins一键部署java项目

一、搭建jenkins 链接: https://pan.baidu.com/s/1jzx15PiyI8EhLd_vg7q8bw 提取码: ydhl 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 直接使用docker导入镜像&#xff0c;运行就好 docker run -di --name jenkins -p 8080:8080 -v /home/jenkins_home:/var/je…

【人工智能】NLP入门指南:自然语言处理基础全解析

文章目录 前言一、NLPNLP&#xff08;自然语言处理&#xff09;NLU&#xff08;自然语言理解&#xff09;NLG&#xff08;自然语言生成&#xff09; 二、分词1.什么是分词2.常见的分词工具3.jieba分词 三、词向量1.什么是词向量2.文本张量表示方法3.常见的词向量模型3.1 ont-ho…

15.4 zookeeper java client之Curator使用(❤❤❤❤❤)

Curator使用 1. 为什么使用Curator对比Zookeeper原生2. 集成Curator2.1 依赖引入curator-frameworkcurator-recipes2.2 `yml`配置连接信息2.3 CuratorConfig配置类2.4 Curator实现Zookeeper分布式锁业务2.4.1 业务:可重入锁和不可重入锁可重入锁和不可重入锁InterProcessMutex …

scratch魔法门 2024年6月scratch四级 中国电子学会图形化编程 少儿编程等级考试四级真题和答案解析

目录 scratch魔法门 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、pyt…

基于JAVA的美甲店员工管理系统,源码、部署+讲解

摘 要 随着社会科技的飞速发展和进步&#xff0c;网络技术的应用已经深入到生活的方方面面。在这样的背景下&#xff0c;企事业单位的绩效考评体系也受到了极大的影响和冲击。传统的绩效考评方式已经无法满足现代社会的高效需求&#xff0c;因此&#xff0c;研发一款智能化、高…

42 PCB布线叠层与阻抗介绍43 PCB布线过孔添加与设置44 差分对添加与设置45 布线间距规则与介绍

42 PCB布线叠层与阻抗介绍&&43 PCB布线过孔添加与设置&44 差分对添加与设置&&45 布线间距规则与介绍 第一部分 42 PCB布线叠层与阻抗介绍1 板子是怎么来的。2 四层板为例&#xff0c;做叠层和阻抗计算。 第二部分 43 PCB布线过孔添加与设置介绍PCBEdotor中…

c#中的BitConverter的java实现

最近在做c#项目的java迁移&#xff0c;发现部分C#方法java中没有对应实现如图&#xff1a; 且java中的数字类型都是有符号的所以转无符号的时候需要进行手动对符号位& 0xFFFF进行处理&#xff0c;目前只整理了项目中使用到的方法&#xff0c;后续有用到其他方法在进行追加如…

linux学习记录(一)--------目录及文件操作

文章目录 前言Linux目录及文件操作1.Linux目录结构2.常用的Linux命令3.vi编辑器的简单使用4.vi的两个模式 前言 小白学习linux记录有错误随时指出~ Linux目录及文件操作 Linux采用Shell命令->操作文件 1.Linux目录结构 根目录&#xff1a;/ 用户目录&#xff1a;~或者/ho…

H5+JS 4096小游戏

主要实现 1.使用WASD或方向按钮控制游戏 2.最高值4096&#xff0c;玩到4096视为胜利 3.随机生成2、4、8方块 4.移动方块 5.合并方块 JS代码干了什么 初始化游戏界面&#xff1a;创建游戏板和控制按钮。 定义游戏相关变量&#xff1a;如棋盘大小、棋盘状态、得分等。 初始化棋…

软件测试生命周期、BUG描述与处理策略

软件测试的生命周期 需求分析&#xff1a;需求是否完整、是否正确 测试计划&#xff1a;确定由谁测试、测试的起止时间、设计哪些模块 测试设计、测试开发&#xff1a;写测试用例&#xff08;手工、自动化测试用例&#xff09;、编写测试工具 执行测试用例 测试评估&…

面向未来的S2B2C电商供应链系统发展趋势与创新探索

S2B2C电商供应链系统的发展趋势及创新方向。首先分析当前市场环境和消费者需求的变化&#xff0c;如个性化消费、即时配送、绿色环保等趋势对供应链系统的影响。随后&#xff0c;预测并讨论未来供应链系统可能的技术革新&#xff0c;如物联网&#xff08;IoT&#xff09;在物流…

【系统架构设计师】二十四、安全架构设计理论与实践①

目录 一、安全架构概述 1.1 信息安全面临的威胁 1.1.1 安全威胁分类 1.1.2 常见的安全威胁 1.2 安全架构的定义和范围 二、安全模型 2.1 状态机模型 2.2 Bell-LaPadula模型 2.3 Biba模型 2.4 Clark-Wilson模型 2.5 Chinese Wall 模型 往期推荐 一、安全架构概述 1…

基于LoRA和AdaLoRA微调Qwen1.5-0.5B-Chat

本文只开放基于LoRA和AdaLoRA微调代码,具体技术可以自行学习。 Qwen1.5-0.5B-Chat权重路径:https://huggingface.co/Qwen/Qwen1.5-0.5B 数据集路径:https://github.com/DB-lost/self-llm/blob/master/dataset/huanhuan.json 1. 知识点 LoRA, AdaLoRA技术 具体技术可以去看…