基于MM32F3270以太网Server_Socket使用

上一节我们对tcp的报文和连接过程做了介绍,本节通过socket的方式对整个通信过程再次进行一次整理(使用socket方式易于加深对以太网通信过程的理解,在此讲解使用的是完整版socket)。
服务器端初始化
1)调用socket,向内核申请一个套接字sock
2)调用bind将sock与服务器端的ip与port绑定
3)调用listen将套接字设为监听模式,准备接收客户端连接请求
4)调用accept等待并接收客户端的连接请求,建立好tcp连接后,该函数会返回一个新的已连接套接字connected
创建连接
1)客户端调用socket创建套接字
2)调用connect,向服务器发送连接请求
3)connect会发送一个请求syn段并阻塞等待服务器应答(第一次握手)
4)服务器收到syn,会给客户端发送一个确认应答ack,同时发送一个请求(syn)建立连接(第二次握手)
5)客户端收到服务器发的syn+ack段,表明客户端连接已建立成功,进入已连接状态。客户端再向服务器发送一个ack段,服务器收到后则服务器连接成功
数据传输
1)服务器端使用accept连接建立成功后(通信双方可同时写数据,支持全双工),调用read开始读数据,若没有数据则阻塞等待
2)客户端调用write向服务器发送数据请求,客户端收到之后调用read处理请求,此过程服务器调用read阻塞等待
3)服务器调用write将处理好的请求发送给客户端,再次调用read等待下一个请求
4)服务器收到syn,会给客户端发送一个确认应答ack,同时发送一个请求(syn)建立连接(第二次握手)
4)客户端收到后从read返回,发送下一条请求,如此循环下去
断开连接
1)没有数据,则客户端调用close关闭连接,给服务器发送一个断开连接请求fin段(第一次握手)
2)服务器收到客户端的fin段,给客户端发送一个确认应答ack段,表明同意断开连接。客户端收到ack段并调用read返回0,表明客户端连接已经断开(第二次握手)
3)read返回0后,服务器知道客户端已经断开连接,它也调用close关闭连接,给客户端发送一个断开连接请求fin段(第三次握手)
4)客户端收到服务器发送的fin段,就给服务器一个确认应答ack段,表明同意断开连接。客户端进入time_wait状态,服务器收到客户端的ack段后也断开连接
实验使用mb-039开发板,在应用工程中使用lwip+freertos,实验展示如何制作一个tcp server_socket,并收发数据,实验使用到的硬件如下:
如图是mb-039(完整原理图可以通过mm32官网下载)的ethermac部分。
各个信号引脚对应如下:
server_socket实验用到的api大部分在前面已经进行讲解(只是对netconn接口编辑方式进行二次封装),本节只介绍一个比较关键的api:setsockopt(s,level,optname,opval,optlen)。
从名称中就可以看出函数功能用于设置套接字的一些选项,我们关注一下参数:
(1)level有多个常用的选项
sol_socket:表示在socket层
ipproto_tcp:表示在tcp层
ipproto_ip:表示在ip层
(2)optname 表示该层的具体选项名称
level为sol_socket时,有以下选项:so_reuseaddr(允许重用本地地址和端口)、
so_sndtimeo(设置发送数据超时时间)、so_sndtimeo(设置接收数据超时时间)、so_rcvbuf(设置发送数据缓冲区大小)等。
level为ipproto_tcp时,有以下选项:tcp_nodelay(不使用nagle算法)、tcp_keepalive(设置tcp保活时间)等。
level为ipproto_ip选项,有以下选项:ip_ttl(设置生存时间)、ip_tos(设置服务类型)等。
实现server_socket函数:
static void server_socket(void* thread_param){ int sock = -1, connected; char* recv_data; struct sockaddr_in server_addr, client_addr; socklen_t sin_size; int recv_data_len; printf(the local port number is%dnn, local_port); recv_data = (char*)pvportmalloc(recv_data); if (recv_data == null) { printf(no memoryn); goto __exit; } sock = socket(af_inet, sock_stream, 0); if (sock = 0) closesocket(sock); if (recv_data) free(recv_data);}  
1)进入监听状态
2)阻塞应用线程直至与远端主机建立tcp连接,建立成功后远程主机的信息将保持在连接句柄中(connected)
3)对套接字connected进行设置:在tcp层,不使用nagle算法
4)处理客户端的连接请求,接收远程主机信息
5)将接收的数据进行转发
6)主动关闭客户端的连接
到这里已经完成了server_socket函数的创建,看一下pc的ip地址,设备需要处于同一网段方便测试。打开命令行窗口输入:ipconfig
pc的地址为:192.168.105.34,在sys_arch.h文件中对dest_ip_addr0 、dest_ip_addr1、dest_ip_addr2、dest_ip_addr3进行修改,dest_port 随意修改。
#define local_port 2021#define ip_addr0 192#define ip_addr1 168#define ip_addr2 105#define ip_addr3 26  
将程序下载入开发板中,使用netassist进行如下设置:
1)协议设置,此时设备为server,则pc为client
2)设置远程主机地址(即设备地址)
3)端口号
点击连接,若提示连接失败,则ping一下开发板地址,可以正常ping通则检查端口号;如果无法ping通则需要对工程进行检查。
任意输入字符进行发送。
通过上图可以观察到发送成功,并且设备返回数据与发送数据一致,表明实验成功。
实验程序请登录我们的官网下载mm32f3270 sdk,工程路径如下:
~mm32f3270_lib_samples_v0.90demo_appethernet_demoeth_rtosfreertos_server_socket
来源:灵动mm32mcu


IHS:中美贸易冲突冲击智能手机出货量 2019Q1手机屏出货量下调9%
三星Galaxy S8或将采用双扬声器 可能应用Harman技术
以无人机的内部构造详谈多轴飞行器硬件技术
蓄电池在低温下的保养方法解析
华米米动手表青春版评测 一款续航足够持久的运动手表
基于MM32F3270以太网Server_Socket使用
特朗普打击中国技术投资,半导体遭殃!
力士乐二通流量阀的技术特征是怎样的
分析电子火折子的电路原理
准同步的功率集成电路ICE2QR0665的性能特点及应用
红米4A评测:双11手机单品销量第一 怎么样好不好用?
OPPOA77大陆版曝光,双摄与OPPOR11类似
华为P9拆解图赏
看中美民间合作趋势,美国也想「窃取」中国技术
Kensington最新推出SD6000 Docking Station
RFID的应用与发展:RFID为企业创造了价值
CS5266搭配MA8621设计typec转HDMI带PD和TF卡功能
不喜欢iPhone7红色特别版的白色面板?教你100元打造黑红版!
欧美多家电池企业在中国展开激烈竞争 我国如何反击
被誉为“小米5美”的5款小米手机,小米note2排名第二