嵌入式学习第二十六天!(网络传输:TCP编程)

这篇具有很好参考价值的文章主要介绍了嵌入式学习第二十六天!(网络传输:TCP编程)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TCP通信:

    1. TCP发端:

        socket  ->  connect  ->  send  ->  recv  ->  close

    2. TCP收端:

        socket  ->  bind  ->  listen  ->  accept  -> recv  ->  send  ->  close

    3. TCP需要用到的函数:

        1. connect:

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

              功能:发送链接请求

              参数:

                  sockfd:套接字文件描述符

                  addr:目的地址存放空间首地址

                  addrlen:IP地址的大小

              返回值:

                   成功返回0
                   失败返回-1

        2. send:

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

              功能:发送数据

              参数:

                  sockfd:文件描述符

                  buf:发送数据空间首地址

                  flags:属性默认为0

              返回值:

                  成功返回实际发送字节数
                  失败返回-1

        3. recv:

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

                功能:接收数据

                参数:

                    sockfd:套接字文件描述符

                    buf:存放数据空间首地址

                    len:最大接收数据的长度

                    flags:属性,默认为0

                返回值:

                    成功返回实际接收字节数
                    失败返回-1 
                    如果对方退出,返回0 

        4. listen:

int listen(int sockfd, int backlog);

                功能:监听客户端发送的连接请求(该函数不会阻塞)

                参数:

                    sockfd:套接字文件描述符

                    backlog:允许等待的尚未被处理的三次握手请求的最大个数

                返回值:

                    成功返回0 
                    失败返回-1 

        5. accept:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

                功能:处理等待连接队列中的第一个连接请求,该函数具有阻塞功能(如果没有人发送链接请求,会阻塞等待)

                参数:

                    socket:套接字文件描述符

                    address:存放IP地址的空间首地址

                    addrlen:存放IP地址大小空间首地址

                返回值:

                    成功返回一个新的文件描述符
                    失败返回-1

        4. TCP编程练习:

                1. 利用TCP实现跨主机的文件发送:

send.c

#include "head.h"

int main(void)
{
	FILE *fd = NULL;
	int sockfd = 0;
	int ret = 0;
	struct sockaddr_in severaddr;
	ssize_t nsize = 0;
	size_t rret = 0;
	char filename[100] = {0};
	char tmpbuff[1024] = {0};

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd == -1)
	{
		perror("fail to socket");
		return -1;
	}
	
	severaddr.sin_family = AF_INET;
	severaddr.sin_port = htons(50000);
	severaddr.sin_addr.s_addr = inet_addr("192.168.1.162");
	ret = connect(sockfd,(struct sockaddr *)&severaddr, sizeof(severaddr));
	if(ret == -1)
	{
		perror("fail to connect");
		return -1;
	}
	
	scanf("%s", filename);
	fd = fopen(filename, "r");
	if(fd == NULL)
	{
		perror("fail to fopen");
		return -1;
	}

	nsize = send(sockfd, filename, strlen(filename), 0);
	if(nsize == -1)
	{
		perror("fail to send");
		return -1;
	}

	while(1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		rret = fread(tmpbuff, 1, sizeof(tmpbuff), fd);
		if(rret == 0)
		{
			break;
		}
		usleep(1000);
		nsize = send(sockfd, tmpbuff, rret, 0);
		if(nsize == -1)
		{
			perror("fail to send");
			return -1;
		}
		
	}
	
	fclose(fd);
	close(sockfd);

	return 0;

}

        在这里,nsize = send(sockfd, tmpbuff, rret, 0);中,必须使用rret作为发送的字节大小,不能用sizeof(tmpbuff),因为如果是二进制文件,不是ASCII码文件,\0可能成为发送的内容,所以在这里rret作为读到的字节数,可以直接作为send的输入。

recv.c

#include "head.h"

int main(void)
{
	FILE *fd = NULL;
	int ret = 0;
	int sockfd = 0;
	int contfd = 0;
	ssize_t nsize = 0;
	char *ptmp = NULL;
	char tmpbuff[1024] = {0};
	struct sockaddr_in serveraddr;

	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(50000);
	serveraddr.sin_addr.s_addr = INADDR_ANY;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd == -1)
	{
		perror("fail to socket");
		return -1;
	}


	ret = bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
	if(ret == -1)
	{
		perror("fail to ret");
		return -1;
	}
	
	ret = listen(sockfd, 10);
	if(ret == -1)
	{
		perror("fail to listen");
		return -1;
	}

	contfd = accept(sockfd, NULL, NULL);
	if(contfd == -1)
	{
		perror("fail to accept");
		return -1;
	}

	nsize = recv(contfd, tmpbuff, sizeof(tmpbuff), 0);
	if(nsize == -1)
	{
		perror("fail to recv");
		return -1;
	}

	fd = fopen(tmpbuff, "w");
	if(fd == NULL)
	{
		perror("fail to fopen");
		return -1;
	}

	while(1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		nsize = recv(contfd, tmpbuff, sizeof(tmpbuff), 0);
		if(nsize <= 0)
		{
			break;
		}
		fwrite(tmpbuff, 1, nsize, fd);
	}

	fclose(fd);
	close(contfd);
	close(sockfd);

	return 0;
}

嵌入式学习第二十六天!(网络传输:TCP编程),网络,学习,tcp/ip文章来源地址https://www.toymoban.com/news/detail-837457.html

到了这里,关于嵌入式学习第二十六天!(网络传输:TCP编程)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【正点原子FPGA连载】 第二十七章OV5640摄像头LCD显示 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

    1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html OV5640是OmniVision(豪威科技)公司生产的一颗CMOS图像传感器,该传感器功耗低、分辨率高以及采集速率快,主

    2024年02月16日
    浏览(58)
  • 【正点原子FPGA连载】第二十三章PS通过VDMA驱动LCD显示实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

    1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html AXI VDMA是Xilinx专门针对视频应用提供的一种高带宽的解决方案,旨在实现AXI4-Stream视频接口和AXI4接口之间的高

    2024年02月04日
    浏览(66)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第六天-Linux信号(物联技术666)

     更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客 物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单

    2024年01月19日
    浏览(57)
  • 《嵌入式入门-模电基础》第二阶段

    科技的不断发展,给计算机行业带来了很多机会, 嵌 入式开发的前景也越来越广阔, 过去的嵌入式是:电器、机械、交通设备。现在的嵌入式是:手机、智能家居、物联网、新能源、新基建、芯片...... 随着国家政策的倾斜,实业发展的需求, 市场对嵌入式人才的“渴求”

    2024年02月16日
    浏览(43)
  • 【小黑嵌入式系统第二课】嵌入式系统的概述(二)——外围设备、处理器、ARM

    板级支持包(BSP) 是商用嵌入式操作系统实现可移植性所采用的一种方案,是硬件抽象层的一种实现。BSP是介于硬件和操作系统中驱动层程序之间的一层,有时也可认为属于操作系统一部分。BSP实现了对操作系统的支持,为上层的驱动程序提供访问硬件设备的函数包。 BSP隔离了

    2024年04月17日
    浏览(69)
  • 第二章 嵌入式系统硬件基础知识

    (1)信号特性 用 “ 逻辑真 ” “ 1 ” 或 “ 确定 ”来表示 高电平 用 “ 逻辑假 ” “ 0 ” 或 “ 不确定 ”来表示 低电平 1和0称为 互补信号 (2)信号转换 1、数字集成电路的分类         按照开关元件的不同,数字集成电路分为两大类:一类是 双极型集成电路

    2024年01月21日
    浏览(71)
  • SpringBoot源码解读与原理分析(二十七)嵌入式Tomcat

    当Web应用需要部署运行时,传统的做法是将项目打包成war包,然后部署到外置的Web容器中(如最常用的Tomcat容器)。 SpringBoot的一大重要特性是支持嵌入式Web容器,基于SpringBoot的Web应用仅凭一个单独的jar包即可独立运行。 8.1.1 嵌入式Tomcat与普通Tomcat 嵌入式Tomcat是一种可以嵌

    2024年02月22日
    浏览(49)
  • 【小黑嵌入式系统第二课】嵌入式系统的概述(二)——外围设备、处理器、ARM、操作系统

    上一课: 【小黑嵌入式系统第一课】嵌入式系统的概述(一)——概念、特点、发展、应用 下一课: 【小黑嵌入式系统第三课】嵌入式系统硬件平台(一)——概述、总线、存储设备(RAMROMFLASH) 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享

    2024年02月08日
    浏览(48)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-C++和QT编程第六天-Qt UDP编程(物联技术666)

    链接:https://pan.baidu.com/s/1-u7GvgM0TLuiy9z7LYQ80Q?pwd=1688 提取码:1688 在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。这里我们还要了解一个名词Socket,也就是常说的“套接字”。 Qt 网络之UDP 网络基础学习是本文要介绍的内容,UDP(User Datagram Protocol即用户数据报

    2024年01月25日
    浏览(53)
  • 第二章 ARM 技术及体系结构【嵌入式系统】

    2023-7-3 14:28:36 以下内容源自《【嵌入式系统】》 仅供学习交流使用 2.1.1 ARM 体系的版本说明 2.1.2 ARM 内核的命名 2.1.3 常用 ARM 处理器系列介绍 ARM7 系列处理器包括 4 种类型的核:ARM7TDMI、ARM7TDMI-S、ARM720T 和 ARM7EJ,其中 ARM7TDMI 是目前应用最广泛的 32 位嵌入式 RISC 处理器,ARM7 系

    2024年02月12日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包