doubao_chat/apps/common/eth/w5500/w5500.c

559 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "w5500.h"
#include "includes.h"
#include "asm/spi.h"
#include "generic/ioctl.h"
//注意:作为服务器需要设置网关和IP在有效(路由器分配的IP)的同一个网段下,局域网客户端才能连接
//#error "err notece !!!"//务必注意:配置的网关和IP地址需要在路由器分配的IP同一段网络,否则无法通信
static const unsigned char gateway_ip[4] = {192, 168, 0, 1}; //网关参数,默认192.168.31.1
static const unsigned char ip_addr[4] = {192, 168, 0, 199}; //本机IP地址,默认192.168.31.199
static const unsigned char sub_mask[4] = {255, 255, 255, 0}; //子网掩码,默认255.255.255.0
static const unsigned char phy_addr[6] = {0x0c, 0x29, 0xab, 0x7c, 0x00, 0x01}; //网卡物理地址mac地址(第一个字节必须为偶数),默认0x0c29ab7c0001
#if SPI_USE_DEV
static void *spi_handler = NULL;
#else
#define SPI_DLY_US 0 //使用IO模拟翻转时候的时钟跳变延时
#endif
/*******************************************************************************
* 函数名 : SPI_Configuration
* 描述 : W5500 SPI初始化配置(STM32 SPI1)
* 输入 : 无
* 输出 : 无
* 返回值 : 无
* 说明 : 无
*******************************************************************************/
static void *SPI_Configuration(void)
{
#if SPI_USE_DEV
if (!spi_handler) {
spi_handler = dev_open((unsigned char *)SPI_DEV_NAME, NULL);
}
W5500_SCLK_SET_HD(1);
return &spi_handler;
#else
W5500_SCLK_SET_HD(1);
return NULL;
#endif
}
/********************************************************************
*函数名:W5500_io_init
*功 能:W5500 IO 初始化
*参 数:interrupt_callback_func中断回调函数
*返回值:无
*********************************************************************/
void W5500_io_init(void (*interrupt_callback_func)(void))
{
W5500_IO_INIT();
SPI_Configuration();
port_wakeup_reg(W5500_INT_EVENT, W5500_INT_IO, W5500_INT_EDGE, interrupt_callback_func);
}
/********************************************************************
*函数名:SPI_Read_Byte
*功 能:SPI读取一个字节数据
*参 数:无
*返回值:读取的数据
*********************************************************************/
static unsigned char SPI_Read_Byte(void)
{
unsigned char i = 0;
#if SPI_USE_DEV
if (spi_handler) {
dev_ioctl(spi_handler, IOCTL_SPI_READ_BYTE, &i);
/*dev_read(spi_handler,&i,1);*/
}
return i;
#else
unsigned char rByte = 0;
W5500_SCLK_SET(0);
w5500_delay_us(SPI_DLY_US);
for (i = 0; i < 8; i++) {
W5500_SCLK_SET(1);
w5500_delay_us(SPI_DLY_US);
rByte <<= 1;
rByte |= W5500_MISO_GET();
w5500_delay_us(SPI_DLY_US);
W5500_SCLK_SET(0);
w5500_delay_us(SPI_DLY_US);
}
return rByte;
#endif
}
/********************************************************************
*函数名:SPI_SendByte
*功 能:SPI发送一个字节数据
*参 数:dt:待发送的数据
*返回值:无
*********************************************************************/
static void SPI_Send_Byte(unsigned char dt)
{
#if SPI_USE_DEV
if (spi_handler) {
dev_ioctl(spi_handler, IOCTL_SPI_SEND_BYTE, dt);
/*dev_write(spi_handler,(unsigned char*)&dt,1);*/
}
#else
unsigned char i = 0;
W5500_SCLK_SET(0);
for (i = 0; i < 8; i++) {
w5500_delay_us(SPI_DLY_US);
W5500_SCLK_SET(0);
w5500_delay_us(SPI_DLY_US);
if ((dt << i) & 0x80) {
W5500_MOSI_SET(1);
} else {
W5500_MOSI_SET(0);
}
w5500_delay_us(SPI_DLY_US);
W5500_SCLK_SET(1);
w5500_delay_us(SPI_DLY_US);
}
W5500_SCLK_SET(0);
#endif
}
/********************************************************************
*函数名:SPI_Send_Short
*功 能:SPI发送2个字节数据
*参 数:dt:待发送的数据
*返回值:无
*********************************************************************/
void SPI_Send_Short(unsigned short dt)
{
SPI_Send_Byte((unsigned char)(dt / 256)); //写数据高位
SPI_Send_Byte(dt); //写数据低位
}
/********************************************************************
*函数名:Write_W5500_1Byte
*功 能:W5500写寄存器
*参 数:reg寄存器,dat写的值
*返回值:无
*********************************************************************/
void Write_W5500_1Byte(unsigned short reg, unsigned char dat)
{
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM1 | RWB_WRITE | COMMON_R); //通过SPI写控制字节,1个字节数据长度,写数据,选择通用寄存器
SPI_Send_Byte(dat);//写1个字节数据
W5500_CS_SET(1); //置W5500的SCS为高电平
}
/********************************************************************
*函数名:Write_W5500_2Byte
*功 能:通过SPI向指定地址寄存器写2个字节数据
*参 数:reg:16位寄存器地址,dat:16位待写入的数据(2个字节)
*返回值:无
*********************************************************************/
void Write_W5500_2Byte(unsigned short reg, unsigned short dat)
{
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM2 | RWB_WRITE | COMMON_R); //通过SPI写控制字节,2个字节数据长度,写数据,选择通用寄存器
SPI_Send_Short(dat);//写16位数据
W5500_CS_SET(1); //置W5500的SCS为高电平
}
/********************************************************************
*函数名:Write_W5500_nByte
*功 能:通过SPI向指定地址寄存器写n个字节数据
*参 数:reg:16位寄存器地址,*dat_ptr:待写入数据缓冲区指针,
* size:待写入的数据长度
*返回值:无
*********************************************************************/
void Write_W5500_nByte(unsigned short reg, unsigned char *dat_ptr, unsigned short size)
{
unsigned short i;
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(VDM | RWB_WRITE | COMMON_R); //通过SPI写控制字节,N个字节数据长度,写数据,选择通用寄存器
for (i = 0; i < size; i++) { //循环将缓冲区的size个字节数据写入W5500
SPI_Send_Byte(*dat_ptr++);//写一个字节数据
}
W5500_CS_SET(1); //置W5500的SCS为高电平
}
/********************************************************************
*函数名:Write_W5500_SOCK_1Byte
*功 能:通过SPI向指定端口寄存器写1个字节数据
*参 数:s:端口号,reg:16位寄存器地址,dat:待写入的数据
*返回值:无
*********************************************************************/
void Write_W5500_SOCK_1Byte(SOCKET s, unsigned short reg, unsigned char dat)
{
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM1 | RWB_WRITE | (s * 0x20 + 0x08)); //通过SPI写控制字节,1个字节数据长度,写数据,选择端口s的寄存器
SPI_Send_Byte(dat);//写1个字节数据
W5500_CS_SET(1); //置W5500的SCS为高电平
}
/********************************************************************
*函数名:Write_W5500_SOCK_2Byte
*功 能:通过SPI向指定端口寄存器写2个字节数据
*参 数:s:端口号,reg:16位寄存器地址,dat:16位待写入的数据(2个字节)
*返回值:无
*********************************************************************/
void Write_W5500_SOCK_2Byte(SOCKET s, unsigned short reg, unsigned short dat)
{
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM2 | RWB_WRITE | (s * 0x20 + 0x08)); //通过SPI写控制字节,2个字节数据长度,写数据,选择端口s的寄存器
SPI_Send_Short(dat);//写16位数据
W5500_CS_SET(1); //置W5500的SCS为高电平
}
/********************************************************************
*函数名:Write_W5500_SOCK_4Byte
*功 能:通过SPI向指定端口寄存器写4个字节数据
*参 数:s:端口号,reg:16位寄存器地址,*dat_ptr:待写入的4个字节缓冲区指针
*返回值:无
*********************************************************************/
void Write_W5500_SOCK_4Byte(SOCKET s, unsigned short reg, unsigned char *dat_ptr)
{
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM4 | RWB_WRITE | (s * 0x20 + 0x08)); //通过SPI写控制字节,4个字节数据长度,写数据,选择端口s的寄存器
SPI_Send_Byte(*dat_ptr++);//写第1个字节数据
SPI_Send_Byte(*dat_ptr++);//写第2个字节数据
SPI_Send_Byte(*dat_ptr++);//写第3个字节数据
SPI_Send_Byte(*dat_ptr++);//写第4个字节数据
W5500_CS_SET(1); //置W5500的SCS为高电平
}
/********************************************************************
*函数名:Read_W5500_1Byte
*功 能:读W5500指定地址寄存器的1个字节数据
*参 数:reg:16位寄存器地址
*返回值:读取到寄存器的1个字节数据
*********************************************************************/
unsigned char Read_W5500_1Byte(unsigned short reg)
{
unsigned char i;
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM1 | RWB_READ | COMMON_R); //通过SPI写控制字节,1个字节数据长度,读数据,选择通用寄存器
i = SPI_Read_Byte();
W5500_CS_SET(1);//置W5500的SCS为高电平
return i;//返回读取到的寄存器数据
}
/********************************************************************
*函数名:Read_W5500_SOCK_1Byte
*功 能:读W5500指定端口寄存器的1个字节数据
*参 数:s:端口号,reg:16位寄存器地址
*返回值:读取到寄存器的1个字节数据
*********************************************************************/
unsigned char Read_W5500_SOCK_1Byte(SOCKET s, unsigned short reg)
{
unsigned char i;
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM1 | RWB_READ | (s * 0x20 + 0x08)); //通过SPI写控制字节,1个字节数据长度,读数据,选择端口s的寄存器
i = SPI_Read_Byte();
W5500_CS_SET(1);//置W5500的SCS为高电平
return i;//返回读取到的寄存器数据
}
/********************************************************************
*函数名:Read_W5500_SOCK_2Byte
*功 能:读W5500指定端口寄存器的2个字节数据
*参 数:s:端口号,reg:16位寄存器地址
*返回值:读取到寄存器的2个字节数据(16位)
*********************************************************************/
unsigned short Read_W5500_SOCK_2Byte(SOCKET s, unsigned short reg)
{
unsigned short i;
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(reg);//通过SPI写16位寄存器地址
SPI_Send_Byte(FDM2 | RWB_READ | (s * 0x20 + 0x08)); //通过SPI写控制字节,2个字节数据长度,读数据,选择端口s的寄存器
i = SPI_Read_Byte();
i *= 256;
i += SPI_Read_Byte(); //读取低位数据
W5500_CS_SET(1);//置W5500的SCS为高电平
return i;//返回读取到的寄存器数据
}
/********************************************************************
*函数名:Read_SOCK_Data_Buffer
*功 能:从W5500接收数据缓冲区中读取数据
*参 数:s:端口号,*dat_ptr:数据保存缓冲区指针
*返回值:读取到的数据长度,rx_size个字节
*********************************************************************/
unsigned short Read_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr)
{
unsigned short rx_size;
unsigned short offset, offset1;
unsigned short i;
unsigned char j;
rx_size = Read_W5500_SOCK_2Byte(s, Sn_RX_RSR);
if (rx_size == 0) {
return 0; //没接收到数据则返回
}
if (rx_size > SOCKET_MAX_SIZE) {
rx_size = SOCKET_MAX_SIZE;
}
offset = Read_W5500_SOCK_2Byte(s, Sn_RX_RD);
offset1 = offset;
offset &= (S_RX_SIZE - 1); //计算实际的物理地址
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(offset);//写16位地址
SPI_Send_Byte(VDM | RWB_READ | (s * 0x20 + 0x18)); //写控制字节,N个字节数据长度,读数据,选择端口s的寄存器
if ((offset + rx_size) < S_RX_SIZE) { //如果最大地址未超过W5500接收缓冲区寄存器的最大地址
for (i = 0; i < rx_size; i++) { //循环读取rx_size个字节数据
j = SPI_Read_Byte(); //读取1个字节数据
*dat_ptr = j; //将读取到的数据保存到数据保存缓冲区
dat_ptr++;//数据保存缓冲区指针地址自增1
}
} else { //如果最大地址超过W5500接收缓冲区寄存器的最大地址
offset = S_RX_SIZE - offset;
for (i = 0; i < offset; i++) { //循环读取出前offset个字节数据
j = SPI_Read_Byte(); //读取1个字节数据
*dat_ptr = j; //将读取到的数据保存到数据保存缓冲区
dat_ptr++;//数据保存缓冲区指针地址自增1
}
W5500_CS_SET(1); //置W5500的SCS为高电平
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(0x00);//写16位地址
SPI_Send_Byte(VDM | RWB_READ | (s * 0x20 + 0x18)); //写控制字节,N个字节数据长度,读数据,选择端口s的寄存器
for (; i < rx_size; i++) { //循环读取后rx_size-offset个字节数据
j = SPI_Read_Byte(); //读取1个字节数据
*dat_ptr = j; //将读取到的数据保存到数据保存缓冲区
dat_ptr++;//数据保存缓冲区指针地址自增1
}
}
W5500_CS_SET(1); //置W5500的SCS为高电平
offset1 += rx_size; //更新实际物理地址,即下次读取接收到的数据的起始地址
Write_W5500_SOCK_2Byte(s, Sn_RX_RD, offset1);
Write_W5500_SOCK_1Byte(s, Sn_CR, RECV);//发送启动接收命令
return rx_size;//返回接收到数据的长度
}
/********************************************************************
*函数名:Write_SOCK_Data_Buffer
*功 能:将数据写入W5500的数据发送缓冲区
*参 数:s:端口号,*dat_ptr:数据保存缓冲区指针,size:待写入数据的长度
*返回值:无
*********************************************************************/
void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
{
unsigned short offset, offset1;
unsigned short i = 0;
offset = Read_W5500_SOCK_2Byte(s, Sn_TX_WR);
offset1 = offset;
offset &= (S_TX_SIZE - 1); //计算实际的物理地址
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(offset);//写16位地址
SPI_Send_Byte(VDM | RWB_WRITE | (s * 0x20 + 0x10)); //写控制字节,N个字节数据长度,写数据,选择端口s的寄存器
if ((offset + size) < S_TX_SIZE) { //如果最大地址未超过W5500发送缓冲区寄存器的最大地址
for (i = 0; i < size; i++) { //循环写入size个字节数据
SPI_Send_Byte(*dat_ptr++);//写入一个字节的数据
}
} else { //如果最大地址超过W5500发送缓冲区寄存器的最大地址
offset = S_TX_SIZE - offset;
for (i = 0; i < offset; i++) { //循环写入前offset个字节数据
SPI_Send_Byte(*dat_ptr++);//写入一个字节的数据
}
W5500_CS_SET(1); //置W5500的SCS为高电平
W5500_CS_SET(0);//置W5500的SCS为低电平
SPI_Send_Short(0x00);//写16位地址
SPI_Send_Byte(VDM | RWB_WRITE | (s * 0x20 + 0x10)); //写控制字节,N个字节数据长度,写数据,选择端口s的寄存器
for (; i < size; i++) { //循环写入size-offset个字节数据
SPI_Send_Byte(*dat_ptr++);//写入一个字节的数据
}
}
W5500_CS_SET(1); //置W5500的SCS为高电平
offset1 += size; //更新实际物理地址,即下次写待发送数据到发送数据缓冲区的起始地址
Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);
Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);//发送启动发送命令
}
/********************************************************************
*函数名:W5500_Hardware_Reset
*功 能:硬件复位W5500
*参 数:无
*返回值:无
*********************************************************************/
void W5500_Hardware_Reset(void)
{
u32 cnt = 0;
W5500_RST_SET(0);//复位引脚拉低
w5500_delay_ms(200);
W5500_RST_SET(1);//复位引脚拉高
w5500_delay_ms(200);
while ((Read_W5500_1Byte(PHYCFGR)&LINK) == 0) { //等待以太网连接完成
cnt++;
w5500_delay_ms(10);
if (cnt > 1000) {
w5500_log("%s %d err \n", __FUNCTION__, __LINE__);
break;
}
}
}
/********************************************************************
*函数名:W5500_ip_addr_get
*功 能:获取注册到W5500的IP地址
*参 数:无
*返回值:IP地址
*********************************************************************/
unsigned int W5500_ip_addr_get(void)
{
return ((ip_addr[0] << 24) | (ip_addr[1] << 16) | (ip_addr[2] << 8) | (ip_addr[3]));
}
/********************************************************************
*函数名:W5500_Init
*功 能:初始化W5500寄存器
*参 数:无
*返回值:无
*********************************************************************/
void W5500_Init(void)
{
unsigned char i = 0;
W5500_io_init(socket_interrupt);//初始化IO,注册socket中断函数
W5500_Hardware_Reset();//硬件复位W5500
Write_W5500_1Byte(MR, RST);//软件复位W5500,置1有效,复位后自动清0
w5500_delay_ms(10);//延时10ms,自己定义该函数
//设置网关(Gateway)的IP地址,Gateway_IP为4字节unsigned char数组,自己定义
//使用网关可以使通信突破子网的局限,通过网关可以访问到其它子网或进入Internet
Write_W5500_nByte(GAR, (unsigned char *)gateway_ip, 4);
//设置子网掩码(MASK)值,SUB_MASK为4字节unsigned char数组,自己定义
//子网掩码用于子网运算
Write_W5500_nByte(SUBR, (unsigned char *)sub_mask, 4);
//设置物理地址,PHY_ADDR为6字节unsigned char数组,自己定义,用于唯一标识网络设备的物理地址值
//该地址值需要到IEEE申请,按照OUI的规定,前3个字节为厂商代码,后三个字节为产品序号
//如果自己定义物理地址,注意第一个字节必须为偶数
Write_W5500_nByte(SHAR, (unsigned char *)phy_addr, 6);
//设置本机的IP地址,IP_ADDR为4字节unsigned char数组,自己定义
//注意,网关IP必须与本机IP属于同一个子网,否则本机将无法找到网关
Write_W5500_nByte(SIPR, (unsigned char *)ip_addr, 4);
//设置发送缓冲区和接收缓冲区的大小,参考W5500数据手册
for (i = 0; i < 8; i++) {
Write_W5500_SOCK_1Byte(i, Sn_RXBUF_SIZE, 0x02); //Socket Rx memory size=2k
Write_W5500_SOCK_1Byte(i, Sn_TXBUF_SIZE, 0x02); //Socket Tx mempry size=2k
}
//设置重试时间,默认为2000(200ms)
//每一单位数值为100微秒
Write_W5500_2Byte(RTR, 200 * 10);
//设置重试次数,默认为255次
//如果重发的次数超过设定值,则产生超时中断(相关的端口中断寄存器中的Sn_IR 超时位(TIMEOUT)置“1”)
Write_W5500_1Byte(RCR, 255);
}
/********************************************************************
*函数名:Socket_Connect
*功 能:TCP模式socket连接
*参 数:s:端口号
*返回值:无
*********************************************************************/
unsigned char Socket_Connect(SOCKET s)
{
Write_W5500_SOCK_1Byte(s, Sn_MR, MR_TCP); //设置socket为TCP模式
Write_W5500_SOCK_1Byte(s, Sn_CR, OPEN); //打开Socket
w5500_delay_ms(5);//延时5ms
if (Read_W5500_SOCK_1Byte(s, Sn_SR) != SOCK_INIT) { //如果socket打开失败
Write_W5500_SOCK_1Byte(s, Sn_CR, CLOSE); //打开不成功,关闭Socket
w5500_log("%s %d err \n", __FUNCTION__, __LINE__);
return FALSE;//返回FALSE(0x00)
}
Write_W5500_SOCK_1Byte(s, Sn_CR, CONNECT); //设置Socket为Connect模式
return TRUE;//返回TRUE,设置成功
}
/********************************************************************
*函数名:Socket_Listen
*功 能:TCP模式设置指定Socket(0~7)作为服务器等待远程主机的连接
*参 数:s:端口号
*返回值:成功返回TRUE(0xFF),失败返回FALSE(0x00)
*说 明:当本机Socket工作在服务器模式时,引用该程序,等等远程主机的连接
* 该程序只调用一次,就使W5500设置为服务器模式
*********************************************************************/
unsigned char Socket_Listen(SOCKET s)
{
Write_W5500_SOCK_1Byte(s, Sn_MR, MR_TCP); //设置socket为TCP模式
Write_W5500_SOCK_1Byte(s, Sn_CR, OPEN); //打开Socket
w5500_delay_ms(5);//延时5ms
if (Read_W5500_SOCK_1Byte(s, Sn_SR) != SOCK_INIT) { //如果socket打开失败
Write_W5500_SOCK_1Byte(s, Sn_CR, CLOSE); //打开不成功,关闭Socket
w5500_log("%s %d err \n", __FUNCTION__, __LINE__);
return FALSE;//返回FALSE(0x00)
}
Write_W5500_SOCK_1Byte(s, Sn_CR, LISTEN); //设置Socket为侦听模式
w5500_delay_ms(5);//延时5ms
if (Read_W5500_SOCK_1Byte(s, Sn_SR) != SOCK_LISTEN) { //如果socket设置失败
Write_W5500_SOCK_1Byte(s, Sn_CR, CLOSE); //设置不成功,关闭Socket
w5500_log("%s %d err \n", __FUNCTION__, __LINE__);
return FALSE;//返回FALSE(0x00)
}
return TRUE;
//至此完成了Socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待Socket中断,
//以判断Socket的连接是否成功。参考W5500数据手册的Socket中断状态
//在服务器侦听模式不需要设置目的IP和目的端口号
}
/********************************************************************
*函数名:Socket_UDP
*功 能:设置指定Socket(0~7)为UDP模式
*参 数:s:端口号
*返回值:成功返回TRUE(0xFF),失败返回FALSE(0x00)
*说 明:如果Socket工作在UDP模式,引用该程序,在UDP模式下,Socket通信不需
* 要建立连接,该程序只调用一次,就使W5500设置为UDP模式
*********************************************************************/
unsigned char Socket_UDP(SOCKET s)
{
Write_W5500_SOCK_1Byte(s, Sn_MR, MR_UDP); //设置Socket为UDP模式*/
Write_W5500_SOCK_1Byte(s, Sn_CR, OPEN); //打开Socket*/
w5500_delay_ms(5);//延时5ms
if (Read_W5500_SOCK_1Byte(s, Sn_SR) != SOCK_UDP) { //如果Socket打开失败
Write_W5500_SOCK_1Byte(s, Sn_CR, CLOSE); //打开不成功,关闭Socket
w5500_log("%s %d err \n", __FUNCTION__, __LINE__);
return FALSE;//返回FALSE(0x00)
} else {
return TRUE;
}
//至此完成了Socket的打开和UDP模式设置,在这种模式下它不需要与远程主机建立连接
//因为Socket不需要建立连接,所以在发送数据前都可以设置目的主机IP和目的Socket的端口号
//如果目的主机IP和目的Socket的端口号是固定的,在运行过程中没有改变,那么也可以在这里设置
}