网络通讯
Socket
- 位置
sys_socket.aclib
- 功能说明
创建一个新的socket,并返回socket句柄。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
address_family | DINT | 地址族 | × | × |
socket_type | DINT | 数据传输方式/套接字类型 | × | × |
protocol | DINT | 传输协议 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
Socket | DINT | 失败返回-1,其余表示新创建的socket句柄。 | × | × |
address_family项的值如下:
名称 | 值 | 含义 |
---|---|---|
SOCKET_AF_UNSPEC | 0 | unspecified |
SOCKET_AF_LOCAL | 1 | local to host(pipes, portals) |
SOCKET_AF_UNIX | 1 | backward compatibility |
SOCKET_AF_INET | 2 | internetwork: TCP, UDP, etc. |
SOCKET_AF_IMPLINK | 3 | arpanet imp addresses |
SOCKET_AF_PUP | 4 | pup protocols: e.g. BSP |
SOCKET_AF_CHAOS | 5 | mit CHAOS protocols |
SOCKET_AF_NS | 6 | XEROX NS protocols |
SOCKET_AF_ISO | 7 | ISO protocols |
SOCKET_AF_OSI | 7 | OSI protocols |
SOCKET_AF_ECMA | 8 | european computer manufacturers |
SOCKET_AF_DATAKIT | 9 | datakit protocols |
SOCKET_AF_CCITT | 10 | CCITT protocols, X.25 etc |
SOCKET_AF_SNA | 11 | IBM SNA |
SOCKET_AF_DECnet | 12 | DECnet |
SOCKET_AF_DLI | 13 | DEC Direct data link interface |
SOCKET_AF_LAT | 14 | LAT |
SOCKET_AF_HYLINK | 15 | NSC Hyperchannel |
SOCKET_AF_APPLETALK | 16 | Apple Talk |
SOCKET_AF_ROUTE | 17 | Internal Routing Protocol |
SOCKET_AF_LINK | 18 | Link layer interface |
SOCKET_pseudo_AF_XTP | 19 | eXpress Transfer Protocol (no AF) |
SOCKET_AF_COIP | 20 | connection-oriented IP, aka ST II |
SOCKET_AF_CNT | 21 | Computer Network Technology |
SOCKET_pseudo_AF_RTIP | 22 | Help Identify RTIP packets |
SOCKET_AF_IPX | 23 | Novell Internet Protocol |
SOCKET_AF_SIP | 24 | Simple Internet Protocol |
SOCKET_pseudo_AF_PIP | 25 | Help Identify PIP packets |
SOCKET_AF_MAX | 26 | Max definition |
SOCKET_AF_INET_BSD | 100 | BSD-specific INET af |
SOCKET_AF_INET_STREAMS | 101 | STREAMS-specific INET af |
socket_type项的值如下:
名称 | 值 | 含义 |
---|---|---|
SOCKET_STREAM | 1 | stream socket |
SOCKET_DGRAM | 2 | datagram socket |
SOCKET_RAW | 3 | raw-protocol interface |
SOCKET_RDM | 4 | reliably-delivered message |
SOCKET_SEQPACKET | 5 | sequenced packet stream |
protocol项的值如下:
名称 | 值 | 含义 |
---|---|---|
SOCKET_IPPROTO_IP | 0 | dummy for IP |
SOCKET_IPPROTO_ICMP | 1 | control message protocol |
SOCKET_IPPROTO_IGMP | 2 | group management protocol |
SOCKET_IPPROTO_GGP | 3 | gateway^2 (deprecated) |
SOCKET_IPPROTO_TCP | 6 | tcp |
SOCKET_IPPROTO_PUP | 12 | pup |
SOCKET_IPPROTO_UDP | 17 | user datagram protocol |
SOCKET_IPPROTO_IDP | 22 | xns idp |
SOCKET_IPPROTO_ND | 77 | UNOFFICIAL net disk proto |
SOCKET_IPPROTO_TLS | 254 | UNOFFICIAL TCP/TLS protocol |
SOCKET_IPPROTO_RAW | 255 | raw IP packet |
SOCKET_IPPROTO_MAX | 256 | Max definition |
示例
示例功能说明 创建一个UDP类型的socket。
变量定义
变量名 数据类型 初值 注释 hSocket DINT 套接字句柄 socket_family DINT SOCKET_AF_INET socket_type DINT SOCKET_DGRAM socket_protocol DINT SOCKET_IPPROTO_UDP CFC示例
ST示例 hSocket := Socket( socket_family , socket_type , socket_protocol);
LD示例
SocketClose
- 位置
sys_socket.aclib
- 功能说明
关闭一个socket。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketClose | DINT | 成功返回0,失败返回-1 | × | × |
示例
示例功能说明 关闭一个socket。
变量定义
变量名 数据类型 初值 注释 hSocket DINT 套接字句柄 retClose DINT CFC示例
ST示例 retClose := SocketClose( hSocket );
LD示例
SocketBind
- 位置
sys_socket.aclib
- 功能说明
socket绑定。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
address | POINTER TO sockaddr | socket地址指针 | × | × |
address_len | DINT | socket地址结构长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketBind | DINT | 成功返回0,失败返回-1 | × | × |
- 示例
请参考“Socket综合示例-TCP服务器”中关于 SocketBind 的使用。
SocketListen
- 位置
sys_socket.aclib
- 功能说明
socket监听。
- 参数说明
输入参数 | 数据类型 | 描述 | 保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
max_connections | DINT | 允许连接的客户端最大个数 | × | × |
输出参数 | 数据类型 | 描述 | 保持 | 常量 |
---|---|---|---|---|
SocketListen | DINT | 成功返回0,失败返回-1 | × | × |
- 示例
请参考“Socket综合示例-TCP服务器”中关于 SocketListen 的使用。
SocketAccept
- 位置
sys_socket.aclib
- 功能说明
接受一个socket连接。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
client_address | POINTER TO sockaddr | 返回已连接的客户端的socket地址 | × | × |
address_len | POINTER TO DINT | 返回的socket地址结构长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketAccept | DINT | 失败返回-1,其余表示新连接的socket句柄 | × | × |
- 示例
请参考“Socket综合示例-TCP服务器”中关于 SocketAccept 的使用。
SocketConnect
- 位置
sys_socket.aclib
- 功能说明
连接一个客户端。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
server_address | POINTER TO sockaddr | socket地址指针 | × | × |
address_len | DINT | socket地址结构长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketConnect | DINT | 成功返回0,失败返回-1 | × | × |
- 示例
请参考“Socket综合示例-TCP客户端”中关于 SocketConnect 的使用。
SocketSetOption
- 位置
sys_socket.aclib
- 功能说明
设置socket选项。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
level | DINT | socket级别 | × | × |
option_name | DINT | 选项命令字 | × | × |
option_value | POINTER TO DINT | 指向选项值的指针 | × | × |
option_len | DINT | 选项值的长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketSetOption | DINT | 成功返回0,失败返回-1 | × | × |
level和option_name详见sys_socket.aclib中socket_const下的相关字段。
支持的level项有:
名称 | 值 | 含义 |
---|---|---|
SOCKET_SOL | 16#FFFF | 基本socket |
SOCKET_IPPROTO_IP | 0 | IPv4 socket |
SOCKET_IPPROTO_TCP | 6 | TCP socket |
其中,level项为SOCKET_SOL时支持的option_name(即选项命令字)有:
名称 | 值 | 含义 |
---|---|---|
SOCKET_SO_DEBUG | 16#0001 | turn on debugging info recording |
SOCKET_SO_ACCEPTCONN | 16#0002 | socket has had listen() |
SOCKET_SO_REUSEADDR | 16#0004 | allow local address reuse |
SOCKET_SO_KEEPALIVE | 16#0008 | keep connections alive |
SOCKET_SO_DONTROUT | 16#0010 | just use interface addresses |
SOCKET_SO_BROADCAST | 16#0020 | permit sending of broadcast msgs |
SOCKET_SO_USELOOPBACK | 16#0040 | bypass hardware when possible |
SOCKET_SO_LINGER | 16#0080 | linger on close if data present |
SOCKET_SO_OOBINLINE | 16#0100 | leave received OOB data in line |
SOCKET_SO_REUSEPORT | 16#0200 | allow local address & port reuse |
SOCKET_SO_SNDBUF | 16#1001 | send buffer size |
SOCKET_SO_RCVBUF | 16#1002 | receive buffer size |
SOCKET_SO_SNDLOWAT | 16#1003 | send low-water mark |
SOCKET_SO_RCVLOWAT | 16#1004 | receive low-water mark |
SOCKET_SO_SNDTIMEO | 16#1005 | send timeout |
SOCKET_SO_RCVTIMEO | 16#1006 | receive timeout |
SOCKET_SO_ERROR | 16#1007 | get error status and clear |
SOCKET_SO_TYPE | 16#1008 | get socket type |
SOCKET_SO_PROTOTYPE | 16#1009 | get/set protocol type |
SOCKET_SO_HOSTNAME | 16#2001 | get/set host name for tls connections. Needed for SNI(Server Name Indication) |
SOCKET_SO_STARTTLS | 16#3001 | upgrade standard socket to TLS. Works only on sockets with socket type SYSSOCK_TYPE_STARTTLS! |
SOCKET_SO_MULTICAST_IF | IP multicast interface - obsolete only for backward compatibility. |
其中,level项为SOCKET_IPPROTO_IP时支持的option_name(即选项命令字)有:
名称 | 值 | 含义 |
---|---|---|
SOCKET_IP_MULTICAST_IF | 16#9 | IP multicast interface |
SOCKET_IP_MULTICAST_TTL | 16#A | IP multicast TTL (hop limit) |
SOCKET_IP_MULTICAST_LOOP | 16#B | IP multicast loopback |
SOCKET_IP_ADD_MEMBERSHIP | 16#C | Add an IP group membership. |
SOCKET_IP_DROP_MEMBERSHIP | 16#D | Drop an IP group membership. |
SOCKET_IP_DONTFRAGMENT | 16#E | Indicates that data should not be fragmented regardless of the local MTU. Valid only for message oriented protocols (UDP etc). |
其中,level项为SOCKET_IPPROTO_TCP时支持的option_name(即选项命令字)有:
名称 | 值 | 含义 |
---|---|---|
SOCKET_TCP_NODELAY | 16#01 | don't delay send to coalesce packets |
SOCKET_TCP_MAXSEG | 16#02 | set maximum segment size |
- 示例
请参考“Socket综合示例-TCP服务器”中关于 SocketSetOption 的使用。
SocketGetOption
- 位置
sys_socket.aclib
- 功能说明
获取socket选项。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
level | DINT | socket级别 | × | × |
option_name | DINT | 选项命令字 | × | × |
option_value | POINTER TO DINT | 指向选项值的指针 | × | × |
option_len | POINTER TO DINT | 通过指针返回选项值的长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketGetOption | DINT | 成功返回0,失败返回-1 | × | × |
level和option_name与SocketSetOption中的一致。
示例
示例功能说明 获取SOCKET_SO_REUSEADDR选项的值。
变量定义
变量名 数据类型 初值 注释 hSocket DINT iOptValue DINT 选项值 iOptValueLen DINT iOprRet DINT CFC示例
ST示例 iOprRet := SocketGetOption( hSocket , SOCKET_SOL , SOCKET_SO_REUSEADDR , ADR(iOptValue) , ADR(iOptValueLen) );
LD示例
SocketIoctl
位置
sys_socket.aclib
- 功能说明
ioctl设置。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
request | DINT | 命令字 | × | × |
parameter | POINTER TO DINT | 命令字参数 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketIoctl | DINT | 成功返回0,失败返回-1 | × | × |
request项的值详见sys_socket.aclib中socket_const下的相关字段,如下:
名称 | 值 | 含义 |
---|---|---|
SOCKET_FIONREAD | 1 | get num chars available to read |
SOCKET_FIONBIO | 2 | set to non-blocking |
- 示例
请参考“Socket综合示例-TCP服务器”中关于 SocketIoctl 的使用。
SocketRecv
- 位置
sys_socket.aclib
- 功能说明
socket接收数据。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
buffer | POINTER TO BYTE | 接收到的数据的存放地址 | × | × |
buffer_len | DINT | 待接收的数据长度 | × | × |
flags | DINT | 相关标识,无可填0 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketRecv | DINT | 成功返回接收到的字符数,失败返回-1 | × | × |
flags项的值详见sys_socket.aclib中socket_const下的相关字段,如下:
名称 | 值 | 含义 |
---|---|---|
SOCKET_MSG_NONE | 16#0 | no flag |
SOCKET_MSG_OOB | 16#1 | process out-of-band data |
SOCKET_MSG_PEEK | 16#2 | peek at incoming message |
SOCKET_MSG_DONTROUTE | 16#4 | send without using routing tables |
SOCKET_MSG_NONTWAIT | 16#8 | send TCP frame directly without blocking |
- 示例
请参考“Socket综合示例-TCP服务器”和“Socket综合示例-TCP客户端”中关于 SocketRecv 的使用。
SocketRecvfrom
- 位置
sys_socket.aclib
- 功能说明
socket接收数据。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
buffer | POINTER TO BYTE | 接收到的数据的存放地址 | × | × |
buffer_len | DINT | 待接收的数据长度 | × | × |
flags | DINT | 相关标识,无可填0 | × | × |
from_address | POINTER TO sockaddr | socket地址 | × | × |
from_address_len | POINTER TO DINT | socket地址结构长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketRecvfrom | DINT | 成功返回接收到的字符数,失败返回-1 | × | × |
flags项与SocketRecv中的flags项相同。
- 示例
请参考“Socket综合示例-UDP服务器”中关于 SocketRecvfrom 的使用。
SocketSend
- 位置
sys_socket.aclib
- 功能说明
socket发送数据。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
buffer | POINTER TO BYTE | 待发送数据缓存 | × | × |
buffer_len | DINT | 待发送数据长度,单位Byte | × | × |
flags | DINT | 相关标识,无可填0 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketSend | DINT | 成功返回已发送的字符数,失败返回-1 | × | × |
flags项与SocketRecv中的flags项相同。
- 示例
请参考“Socket综合示例-TCP服务器”和“Socket综合示例-TCP客户端”中关于 SocketSend 的使用。
SocketSendto
- 位置
sys_socket.aclib
- 功能说明
socket发送数据。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
buffer | POINTER TO BYTE | 待发送数据缓存 | × | × |
buffer_len | DINT | 待发送数据长度,单位Byte | × | × |
flags | DINT | 相关标识,无可填0 | × | × |
from_address | POINTER TO sockaddr | socket地址 | × | × |
from_address_len | POINTER TO DINT | socket地址结构长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketSendto | DINT | 成功返回已发送的字符数,失败返回-1 | × | × |
flags项与SocketRecv中的flags项相同。
- 示例
请参考“Socket综合示例-UDP服务器”中关于 SocketSendto 的使用。
SocketShutdown
- 位置
sys_socket.aclib
- 功能说明
socket关闭。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
howto | DINT | 关闭方式 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketShutdown | DINT | 成功返回0,失败返回-1 | × | × |
关闭方式详见sys_socket.aclib中socket_const下的相关字段:
名称 | 值 | 含义 |
---|---|---|
SOCKET_SD_RECEIVE | 16#0 | Receive is no longer allowed |
SOCKET_SD_SEND | 16#1 | Send is no longer allowed |
SOCKET_SD_BOTH | 16#2 | Send and receive is no longer allowed |
示例
示例功能说明 以SOCKET_SD_BOTH的方式关闭一个套接字。
变量定义
变量名 数据类型 初值 注释 hSocket DINT 套接字句柄 retClose DINT CFC示例
ST示例 retClose := SocketShutdown( hSocket , SOCKET_SD_BOTH );
LD示例
SocketGetHostByName
- 位置
sys_socket.aclib
- 功能说明
根据名称获取主机信息。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
host_name | POINTER TO BYTE | 主机名字符串首地址 | × | × |
host | POINTER TO hostent | 返回的主机描述信息 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketGetHostByName | DINT | 成功返回0,失败返回-1 | × | × |
示例
示例功能说明 先通过SocketGetHostName得到主机名字符串信息,然后再通过SocketGetHostByName获取主机信息。
变量定义
变量名 数据类型 初值 注释 strHostName STRING(80) 主机名 host_info hostent 主机信息 iOprRet DINT CFC示例
ST示例 iOprRet := SocketGetHostName( ADR(strHostName) , SIZEOF(strHostName) ); iOprRet := SocketGetHostByName( ADR(strHostName) , ADR(host_info) );
LD示例
SocketGetHostName
- 位置
sys_socket.aclib
- 功能说明
获取主机名称。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
host_name | POINTER TO BYTE | 存放主机名字符串的首地址 | × | × |
name_len | DINT | 存放字符串的内存空间大小 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketGetHostName | DINT | 成功返回0,失败返回-1 | × | × |
- 示例
请参考“SocketGetHostByName”示例中关于 SocketGetHostName的使用。
SocketHtonl
- 位置
sys_socket.aclib
- 功能说明
主机字节序转换为网络字节序(四字节)。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
host_long | DWORD | 待转换的值 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketHtonl | DWORD | 转换后的值 | × | × |
示例
示例功能说明 将初值为16#12345678的变量进行主机到网络字节序转换,转换结果为16#78563412。
变量定义
变量名 数据类型 初值 注释 host_long DWORD 16#12345678 待转换的值 dwRet DWORD 转换结果为16#78563412 CFC示例
ST示例 dwRet := SocketHtonl( host_long );
LD示例
SocketHtons
- 位置
sys_socket.aclib
- 功能说明
主机字节序转换为网络字节序(二字节)。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
host_short | WORD | 待转换的值 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketHtons | WORD | 转换后的值 | × | × |
示例
示例功能说明 将初值为16#1234的变量进行主机到网络字节序转换,转换结果为16#3412。
变量定义
变量名 数据类型 初值 注释 host_short WORD 16#1234 待转换的值 wRet WORD 转换结果为16#3412 CFC示例
ST示例 wRet := SocketHtons( host_short );
LD示例
SocketNtohl
- 位置
sys_socket.aclib
- 功能说明
网络字节序转换为主机字节序(四字节)。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
net_long | DWORD | 待转换的值 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketNtohl | DWORD | 转换后的值 | × | × |
示例
示例功能说明 将初值为16#12345678的变量进行网络到主机字节序转换,转换结果为16#78563412。
变量定义
变量名 数据类型 初值 注释 net_long DWORD 16#12345678 待转换的值 dwRet DWORD 转换结果为16#78563412 CFC示例
ST示例 dwRet := SocketNtohl( net_long );
LD示例
SocketNtohs
- 位置
sys_socket.aclib
- 功能说明
网络字节序转换为主机字节序(二字节)。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
net_short | WORD | 待转换的值 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketNtohs | WORD | 转换后的值 | × | × |
示例
示例功能说明 将初值为16#1234的变量进行网络到主机字节序转换,转换结果为16#3412。
变量定义
变量名 数据类型 初值 注释 net_short WORD 16#1234 待转换的值 wRet WORD 转换结果为16#3412 CFC示例
ST示例 wRet := SocketNtohs( net_short );
LD示例
SocketInetAddr
- 位置
sys_socket.aclib
- 功能说明
将字符串类型的IP地址转换为四字节的IP地址。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
ip_address_string | POINTER TO BYTE | 待转换的IP地址字符串 | × | × |
ip_address_in_addr | POINTER TO in_addr | 转换后的四字节IP地址 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketInetAddr | DINT | 成功返回0,失败返回-1 | × | × |
示例
示例功能说明 将字符串类型的IP地址'192.168.0.100' 转换为 整形值16#6400A8C0。
变量定义
变量名 数据类型 初值 注释 strIP STRING(15) '192.168.0.100' 待转换的值 in_addr in_addr 转换后的值,in_addr结构中的addr值为16#6400A8C0 iOprRet 是否转换成功 CFC示例
ST示例 iOprRet := SocketInetAddr( ADR(strIP) , ADR(in_addr) );
LD示例
SocketInetNtoa
- 位置
sys_socket.aclib
- 功能说明
将IP地址数据结构转换为字符串类型的IP地址。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
ip_address_in_addr | POINTER TO in_addr | 待转换的IP地址描述信息 | × | × |
ip_address_string | POINTER TO BYTE | 转换后的IP地址字符串 | × | × |
ip_address_string_size | DINT | 存放IP地址字符串的内存空间大小(至少16字节) | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketInetNtoa | DINT | 成功返回0,失败返回-1 | × | × |
示例
示例功能说明 将整形IP地址值16#6400A8C0转换为字符串类型的IP地址'192.168.0.100'。
变量定义
变量名 数据类型 初值 注释 in_addr_input in_addr (addr := 16#6400A8C0) 待转换的值 strIP STRING(15) 转换后的值,结果为'192.168.0.100' iOprRet 是否转换成功 CFC示例
ST示例 iOprRet := SocketInetNtoa( ADR(in_addr_input) , ADR(strIP) , SIZEOF(strIP) );
LD示例
SocketGetAddrInfo
- 位置
sys_socket.aclib
- 功能说明
处理名字到地址以及服务到端口这两种转换,返回的是一个addrinfo的结构(列表)指针而不是一个地址清单。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
hostname | POINTER TO BYTE | 一个主机名或者地址字符串(IPv4的点分十进制串或者IPv6的十六进制字符串) | × | × |
service | POINTER TO BYTE | 一个服务名或者十进制端口号数字符串 | × | × |
hints | POINTER TO addrinfo | 可以是一个空指针,也可以是一个指向某个addrinfo结构的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示 | × | × |
result | POINTER TO addrinfo | 返回的地址信息 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketGetAddrInfo | DINT | 成功返回0,失败返回-1 | × | × |
示例
示例功能说明 先通过SocketGetHostName得到主机名,然后再调用SocketGetAddrInfo获取UDP类型的socket地址信息。
变量定义
变量名 数据类型 初值 注释 strHostName STRING(80) 主机名 strService STRING(80) 服务名 hints_input addrinfo (ai_family := 2,ai_socktype := 2,ai_protocol := 17) 关注的地址信息 hints_result addrinfo 获取到的地址信息 iOprRet DINT 是否转换成功 CFC示例
ST示例 iOprRet := SocketGetHostName( ADR(strHostName) , SIZEOF(strHostName) ); iOprRet := SocketGetAddrInfo( ADR(strHostName) , ADR(strService) , ADR(hints_input) , ADR(hints_result) );
LD示例
SocketGetNameInfo
- 位置
sys_socket.aclib
- 功能说明
以一个套接字地址为参数,返回描述其中的主机的一个字符串和描述其中的服务的另一个字符串。
- 参数说明
输入参数 | 数据类型 | 描述 | 电掉保持 | 常量 |
---|---|---|---|---|
address | POINTER TO sockaddr | socket地址指针 | × | × |
address_len | DINT | socket地址结构长度 | × | × |
host | POINTER TO BYTE | 主机字符串 | × | × |
host_len | DINT | 主机字符串长度,如果为0表示不想返回主机字符串 | × | × |
service | POINTER TO BYTE | 服务字符串 | × | × |
service_len | DINT | 服务字符串长度,如果为0表示不想返回服务字符串 | × | × |
flags | DINT | 相关标识,无可填0 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketGetNameInfo | DINT | 成功返回0,失败返回-1 | × | × |
示例
示例功能说明 获取一个已打开的socket句柄对应的主机名字符串及服务名字符串。
变量定义
变量名 数据类型 初值 注释 socket_addr sockaddr 已打开的socket地址信息 strHostName STRING(80) 主机名 strService STRING(80) 服务名 iFlags DINT iOprRet CFC示例
ST示例 iOprRet := SocketGetNameInfo( ADR(socket_addr) , SIZEOF(socket_addr) , ADR(strHostName) , SIZEOF(strHostName) , ADR(strService) , SIZEOF(strService) , iFlags );
LD示例
GetSocketName
- 位置
sys_socket.aclib
- 功能说明
获取socket句柄对应的socket地址信息。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
address | POINTER TO sockaddr | socket地址指针 | × | × |
address_len | POINTER TO DINT | socket地址结构长度 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
GetSocketName | DINT | 成功返回0,失败返回-1 | × | × |
示例
示例功能说明 获取一个socket句柄对应的socket地址信息。
变量定义
变量名 数据类型 初值 注释 hSocket DINT socket句柄 addr sockaddr socket地址结构 addr_len DINT socket地址结构长度 iOprRet DINT CFC示例
ST示例 iOprRet := GetSocketName( hSocket , ADR(addr) , ADR(addr_len) );
LD示例
SocketSelect
- 位置
sys_socket.aclib
- 功能说明
用来等待socket状态的改变。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
maxfd | DINT | fd_set 结构中待监测的socket个数 | × | × |
read_set | POINTER TO fd_set | 指向fd_set结构的指针,用于检测读类型的集合,如果不关心可填NULL | × | × |
write_set | POINTER TO fd_set | 指向fd_set结构的指针,用于检测写类型的集合,如果不关心可填NULL | × | × |
except_set | POINTER TO fd_set | 指向fd_set结构的指针,用于检测故障状态的集合,如果不关心可填NULL | × | × |
timeout | POINTER TO timeval | 超时时间,如果为NULL 或者timeout->tv_sec=-1或者timeout->tv_usec=-1 表示一直等待,如果 timeout->tv_sec=0 或者 timeout->tv_usec=0 表示不用等待 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketSelect | DINT | 成功返回已准备就绪的socket个数,失败返回-1 | × | × |
示例
请参考“Socket综合示例-TCP服务器”和“Socket综合示例-TCP客户端”中关于 SocketSelect 的使用。
SocketFdSet
- 位置
sys_socket.aclib
- 功能说明
添加一个socket到集合中。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
set | POINTER TO fd_set | 指向socket集合的指针 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketFdSet | DINT | 成功返回0,失败返回-1 | × | × |
- 示例
请参考“Socket综合示例-TCP服务器”和“Socket综合示例-TCP客户端”中关于 SocketFdSet 的使用。
SocketFdClr
- 位置
sys_socket.aclib
- 功能说明
从集合中删除一个socket。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
set | POINTER TO fd_set | 指向socket集合的指针 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketFdClr | DINT | 成功返回0,失败返回-1 | × | × |
- 示例
请参考“Socket综合示例-TCP服务器”和“Socket综合示例-TCP客户端”中关于 SocketFdClr 的使用。
SocketFdIsSet
- 位置
sys_socket.aclib
- 功能说明
检测一个socket在集合中是否已激活。
- 参数说明
输入参数 | 数据类型 | 描述 | 保持 | 常量 |
---|---|---|---|---|
sockfd | DINT | socket句柄 | × | × |
set | POINTER TO fd_set | 指向socket集合的指针 | × | × |
输出参数 | 数据类型 | 描述 | 保持 | 常量 |
---|---|---|---|---|
SocketFdIsSet | BOOL | 已激活返回TRUE,未激活返回FALSE | × | × |
- 示例
请参考“Socket综合示例-TCP服务器”和“Socket综合示例-TCP客户端”中关于 SocketFdIsSet 的使用。
SocketFdZero
- 位置
sys_socket.aclib
- 功能说明
集合清零。
- 参数说明
输入参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
set | POINTER TO fd_set | 指向socket集合的指针 | × | × |
输出参数 | 数据类型 | 描述 | 掉电保持 | 常量 |
---|---|---|---|---|
SocketFdZero | DINT | 成功返回0,失败返回-1 | × | × |
- 示例
请参考“Socket综合示例-TCP服务器”和“Socket综合示例-TCP客户端”中关于 SocketFdZero 的使用。
Socket综合示例-TCP服务器
- 示例功能说明(例程路径:安装目录\example\TCP服务器)
TCP服务器,服务器端口为2000,支持5路连接,并将接收到的数据原封不动的返回。
- 类型定义
ServerClientInfo结构体成员如下:
名称 | 数据类型 | 初始值 | 注释 |
---|---|---|---|
hClientSocket | DINT | 客户端连接句柄 | |
dwRecvTime | UDINT | 最近一次接收到数据的时间 | |
dwIP | DWORD | 客户端IP地址 | |
strIP | STRING(15) | 客户端IP地址 |
- 变量定义
名称 | 数据类型 | 初始值 | 注释 |
---|---|---|---|
bServerSetup | BOOL | 启动服务器 | |
bServerClose | BOOL | 关闭服务器 | |
bInit | BOOL | TRUE | 初始化服务器 |
hSocketListen | DINT | 监听套接字句柄 | |
socket_family | DINT | SOCKET_AF_INET | |
socket_type | DINT | SOCKET_STREAM | |
socket_protocol | DINT | SOCKET_IPPROTO_TCP | |
so_linger | socket_so_value_linger | linger选项 | |
iOptValue | DINT | 选项值 | |
dwSocketBuffSize | DWORD | ||
SockAddrServer | sockaddr_in | 服务器地址信息 | |
iNumMaxClient | DINT | 5 | 服务器最大支持的客户端连接个数 |
iOprRet | DINT | ||
FdSet | fd_set | 套接字事件监测集合 | |
FdSetRun | fd_set | ||
maxFd | DINT | 0 | |
diReady | DINT | ||
tmSlect | timeval | ||
pSetTemp | POINTER TO fd_set | ||
stClientAddress | sockaddr_in | 客户端地址信息 | |
diClientAddressLen | DINT | ||
hClientSocket | DINT | 客户端socket句柄 | |
i | DINT | ||
arrDataRecv | ARRAY[0..255] OF BYTE | 接收到的数据存放内存 | |
diRecvLen | DINT | 接收到的数据长度 | |
diSendLen | DINT | 发送的数据长度 | |
dwRecvTotalLen | DWORD | 累计接收到的数据长度 | |
dwSendTotalLen | DWORD | 累计发送的数据长度 | |
dwTime | UDINT | ||
dwTimeout | UDINT | 20000000 | 客户端超时时间,单位us |
dwServerIpAddr | DWORD | SOCKET_INADDR_ANY | 服务器IP地址 |
wServerPort | WORD | 2000 | 服务器端口号 |
arrClient | ARRAY[0..4] OF ServerClientInfo | 客户端信息 |
- ST示例
IF bInit THEN
bInit := FALSE;
hSocketListen := -1;
(* 初始化客户端信息 *)
FOR i := 0 TO iNumMaxClient BY 1 DO
arrClient[i].hClientSocket := -1;
arrClient[i].dwRecvTime := 0;
arrClient[i].dwIP := 0;
arrClient[i].strIP := '';
END_FOR;
bServerSetup := TRUE;
END_IF;
(* 启动服务器 *)
IF bServerSetup THEN
bServerSetup := FALSE;
hSocketListen := Socket( socket_family , socket_type , socket_protocol);
IF hSocketListen >= 0 THEN
(* 关闭时TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态 *)
so_linger.l_onoff := 1;
so_linger.l_linger := 0;
iOprRet := SocketSetOption( hSocketListen , SOCKET_SOL , SOCKET_SO_LINGER , ADR(so_linger) , SIZEOF(so_linger) );
iOptValue := 1;
(* 设置为可重复使用地址 *)
iOprRet := SocketSetOption( hSocketListen , SOCKET_SOL , SOCKET_SO_REUSEADDR , ADR(iOptValue) , SIZEOF(iOptValue) );
(* 开启Nagle算法 *)
iOprRet := SocketSetOption( hSocketListen , SOCKET_IPPROTO_TCP , SOCKET_TCP_NODELAY , ADR(iOptValue) , SIZEOF(iOptValue) );
(* 设置socket的发送、接收缓存 *)
dwSocketBuffSize := 32*1024;
iOprRet := SocketSetOption( hSocketListen , SOCKET_SOL , SOCKET_SO_SNDBUF , ADR(dwSocketBuffSize) , SIZEOF(dwSocketBuffSize) );
iOprRet := SocketSetOption( hSocketListen , SOCKET_SOL , SOCKET_SO_RCVBUF , ADR(dwSocketBuffSize) , SIZEOF(dwSocketBuffSize) );
(* 设置为非阻塞 *)
iOprRet := SocketIoctl( hSocketListen , SOCKET_FIONBIO , ADR(iOptValue) );
(* 绑定监听端口 *)
SockAddrServer.sin_addr.addr := SocketHtonl( dwServerIpAddr );
SockAddrServer.sin_family := SOCKET_AF_INET;
SockAddrServer.sin_port := SocketHtons( wServerPort );
iOprRet := SocketBind( hSocketListen , ADR(SockAddrServer) , SIZEOF(SockAddrServer) );
IF 0 = iOprRet THEN
(* 监听 *)
iOprRet := SocketListen( hSocketListen , iNumMaxClient );
IF 0 = iOprRet THEN
SocketFdZero( ADR(FdSet) );
SocketFdSet( hSocketListen , ADR(FdSet) );
IF hSocketListen > maxFd THEN
maxFd := hSocketListen;
END_IF;
ELSE
(* 监听失败则关闭创建的socket *)
SocketClose( hSocketListen );
hSocketListen := -1;
END_IF;
ELSE
(* 绑定失败则关闭创建的socket *)
SocketClose( hSocketListen );
hSocketListen := -1;
END_IF;
END_IF;
END_IF;
(* 数据接收处理 *)
IF hSocketListen >= 0 THEN
tmSlect.tv_sec := 0;
tmSlect.tv_usec := 10000;
FdSetRun := FdSet;
diReady := SocketSelect( maxFd + 1 , ADR(FdSetRun) , pSetTemp , pSetTemp , ADR(tmSlect) );
IF diReady > 0 THEN
(* 新的连接请求 *)
IF SocketFdIsSet( hSocketListen , ADR(FdSetRun) ) THEN
hClientSocket := SocketAccept( hSocketListen , ADR(stClientAddress) , ADR(diClientAddressLen) );
FOR i := 0 TO iNumMaxClient BY 1 DO
IF -1 = arrClient[i].hClientSocket THEN
arrClient[i].hClientSocket := hClientSocket;
arrClient[i].dwRecvTime := GetTickCount();
arrClient[i].dwIP := stClientAddress.sin_addr.addr;
SocketInetNtoa( ADR(arrClient[i].dwIP) , ADR(arrClient[i].strIP) , SIZEOF(arrClient[i].strIP) );
EXIT;
END_IF;
END_FOR;
(* 将新的连接句柄添加到集合中 *)
SocketFdSet( hClientSocket , ADR(FdSet) );
IF hClientSocket > maxFd THEN
maxFd := hClientSocket;
END_IF;
END_IF;
(* 客户端连接数据到达 *)
FOR i := 0 TO iNumMaxClient BY 1 DO
IF arrClient[i].hClientSocket >= 0 THEN
IF SocketFdIsSet( arrClient[i].hClientSocket , ADR(FdSetRun) ) THEN
diRecvLen := SocketRecv( arrClient[i].hClientSocket , ADR(arrDataRecv) , SIZEOF(arrDataRecv) , 0 );
IF diRecvLen > 0 THEN
arrClient[i].dwRecvTime := GetTickCount();
(* 将接收到的数据原封不动的返回 *)
diSendLen := SocketSend( arrClient[i].hClientSocket , ADR(arrDataRecv) , diRecvLen , 0 );
IF diSendLen > 0 THEN
dwSendTotalLen := dwSendTotalLen + diSendLen;
END_IF;
dwRecvTotalLen := dwRecvTotalLen + diRecvLen;
END_IF;
END_IF;
END_IF;
END_FOR;
END_IF;
(* 超时检测 *)
FOR i := 0 TO iNumMaxClient BY 1 DO
IF arrClient[i].hClientSocket >= 0 THEN
dwTime := GetTickCount();
dwTime := dwTime - arrClient[i].dwRecvTime;
IF dwTime > dwTimeout THEN
(* 关闭客户端连接,并将客户端连接句柄从集合中移除 *)
SocketFdClr( arrClient[i].hClientSocket , ADR(FdSet) );
SocketClose( arrClient[i].hClientSocket );
arrClient[i].hClientSocket := -1;
arrClient[i].dwRecvTime := 0;
arrClient[i].dwIP := 0;
arrClient[i].strIP := '';
END_IF;
END_IF;
END_FOR;
END_IF;
(* 关闭服务器 *)
IF bServerClose THEN
bServerClose := FALSE;
(* 将监听句柄从集合中移除 *)
SocketFdClr( hSocketListen , ADR(FdSet) );
SocketClose(hSocketListen);
hSocketListen := -1;
(* 将客户端连接句柄从集合中移除 *)
FOR i := 0 TO iNumMaxClient BY 1 DO
IF arrClient[i].hClientSocket >= 0 THEN
SocketFdClr( arrClient[i].hClientSocket , ADR(FdSet) );
SocketClose( arrClient[i].hClientSocket );
arrClient[i].hClientSocket := -1;
arrClient[i].dwRecvTime := 0;
arrClient[i].dwIP := 0;
arrClient[i].strIP := '';
END_IF;
END_FOR;
END_IF;
Socket综合示例-TCP客户端
- 示例功能说明(例程路径:安装目录\example\TCP客户端)
TCP客户端,待连接的服务器端口为2000、IP为192.168.0.254,每次发送10字节数据并接收应答数据。
- 变量定义
名称 | 数据类型 | 初始值 | 注释 |
---|---|---|---|
bClientSetup | BOOL | 建立客户端 | |
bClientClose | BOOL | 关闭客户端 | |
bInit | BOOL | TRUE | 初始化客户端 |
bSend | BOOL | 是否发送数据 | |
bRecv | BOOL | 是否接收数据 | |
hSocket | DINT | 套接字句柄 | |
socket_family | DINT | SOCKET_AF_INET | |
socket_type | DINT | SOCKET_STREAM | |
socket_protocol | DINT | SOCKET_IPPROTO_TCP | |
iOptValue | DINT | 选项值 | |
iOprRet | DINT | ||
SockAddrClient | sockaddr_in | 客户端连接地址信息 | |
FdSet | fd_set | 套接字事件监测集合 | |
FdSetRun | fd_set | ||
maxFd | DINT | 0 | |
diReady | DINT | ||
tmSlect | timeval | ||
pSetTemp | POINTER TO fd_set | ||
wServerPort | WORD | 2000 | 服务器端口号 |
arrDataSend | ARRAY[0..255] OF BYTE | [1,2,3,4,5,6,7,8,9,10,11,245(0)] | 待发送数据存放的内存 |
arrDataRecv | ARRAY[0..255] OF BYTE | 接收到的数据存放内存 | |
diRecvLen | DINT | 接收到的数据长度 | |
diSendLen | DINT | 发送的数据长度 | |
dwRecvTotalLen | DWORD | 累计接收到的数据长度 | |
dwSendTotalLen | DWORD | 累计发送的数据长度 | |
dwExpectSendLen | DWORD | 10 | 期待发送的数据长度 |
strRemoteIP | STRING(15) | '192.168.0.254' | 服务器IP地址 |
dwRemoteIP | DWORD | 服务器IP地址 |
- ST示例
IF bInit THEN
bInit := FALSE;
hSocket := -1;
bClientSetup := TRUE;
END_IF;
(* 创建一个客户端,并连接到服务器 *)
IF bClientSetup THEN
bClientSetup := FALSE;
hSocket := Socket( socket_family , socket_type , socket_protocol);
IF hSocket >= 0 THEN
(* 设置为阻塞模式 *)
iOptValue := 0;
iOprRet := SocketIoctl( hSocket , SOCKET_FIONBIO , ADR(iOptValue) );
(* 连接到服务器 *)
iOprRet := SocketInetAddr( ADR(strRemoteIP) , ADR(dwRemoteIP) );
IF 0 = iOprRet THEN
SockAddrClient.sin_family := SOCKET_AF_INET;
SockAddrClient.sin_port := SocketHtons( wServerPort );
SockAddrClient.sin_addr.addr := dwRemoteIP;
iOprRet := SocketConnect( hSocket , ADR(SockAddrClient) , SIZEOF(SockAddrClient) );
IF 0 = iOprRet THEN
SocketFdZero( ADR(FdSet) );
SocketFdSet( hSocket , ADR(FdSet) );
IF hSocket > maxFd THEN
maxFd := hSocket;
END_IF;
ELSE
(* 连接失败则关闭创建的socket *)
SocketClose( hSocket );
hSocket := -1;
END_IF;
END_IF;
END_IF;
END_IF;
(* 发送数据,并启动接收 *)
IF bSend THEN
bSend := FALSE;
IF hSocket >= 0 THEN
diSendLen := SocketSend( hSocket , ADR(arrDataSend) , dwExpectSendLen , 0 );
IF diSendLen > 0 THEN
dwSendTotalLen := dwSendTotalLen + diSendLen;
bRecv := TRUE; //成功发送数据后 则启动接收
END_IF;
END_IF;
END_IF;
(* 接收数据,接收到数据后停止接收 *)
IF bRecv THEN
IF hSocket >= 0 THEN
tmSlect.tv_sec := 0;
tmSlect.tv_usec := 10000;
FdSetRun := FdSet;
diReady := SocketSelect( maxFd + 1 , ADR(FdSetRun) , pSetTemp , pSetTemp , ADR(tmSlect) );
IF diReady > 0 THEN
IF SocketFdIsSet( hSocket , ADR(FdSetRun) ) THEN
diRecvLen := SocketRecv( hSocket , ADR(arrDataRecv) , SIZEOF(arrDataRecv) , 0 );
IF diRecvLen > 0 THEN
dwRecvTotalLen := dwRecvTotalLen + diRecvLen;
bRecv := FALSE;
END_IF;
END_IF;
END_IF;
END_IF;
END_IF;
(* 关闭一个客户端 *)
IF bClientClose THEN
bClientClose := FALSE;
IF hSocket >= 0 THEN
(* 关闭socket,并将socket句柄从集合中移除 *)
SocketFdClr( hSocket , ADR(FdSet) );
SocketClose( hSocket );
hSocket := -1;
END_IF;
END_IF;
Socket综合示例-UDP服务器
- 示例功能说明(例程路径:安装目录\example\UDP通讯)
UDP服务器,服务器端口为9000,将接收到的数据原封不动的返回。
- 变量定义
名称 | 数据类型 | 初始值 | 注释 |
---|---|---|---|
bServerSetup | BOOL | 启动服务器 | |
bServerClose | BOOL | 关闭服务器 | |
bInit | BOOL | TRUE | 初始化服务器 |
hSocket | DINT | 套接字句柄 | |
socket_family | DINT | SOCKET_AF_INET | |
socket_type | DINT | SOCKET_DGRAM | |
socket_protocol | DINT | SOCKET_IPPROTO_IP | |
ServerSockAddr | sockaddr_in | 服务器地址结构 | |
wServerPort | WORD | 9000 | UDP服务器端口 |
iOprRet | DINT | ||
diOptValue | DINT | ||
dwFlags | DINT | 0 | |
SockAddrRecv | sockaddr_in | 接收到的socket地址信息 | |
SockAddrSend | sockaddr_in | 待发送的socket地址信息 | |
diSockAddrSize | DINT | ||
diRecvedLen | DINT | 接收到的数据长度 | |
dwRecvedTotalLen | DWORD | 累计接收到的数据长度 | |
diSentLen | DINT | 发送的数据长度 | |
dwSentTotalLen | DWORD | 累计发送的数据长度 | |
FdSet | fd_set | 套接字事件监测集合 | |
FdSetRun | fd_set | ||
maxFd | DINT | 0 | |
diReady | DINT | ||
tmSlect | timeval | ||
pSetTemp | POINTER TO fd_set | ||
diLastError | DINT | ||
arrRecv | ARRAY[0..255] OF BYTE | 接收到的数据存放内存 |
- ST示例
IF bInit THEN
bInit := FALSE;
hSocket := -1;
bServerSetup := TRUE;
END_IF;
(* 启动服务器 *)
IF bServerSetup THEN
bServerSetup := FALSE;
hSocket := Socket( socket_family , socket_type , socket_protocol);
IF hSocket >= 0 THEN
diOptValue := 1;
iOprRet := SocketSetOption( hSocket, SOCKET_SOL, SOCKET_SO_REUSEADDR, ADR(diOptValue), SIZEOF(diOptValue));
ServerSockAddr.sin_addr.addr := SOCKET_INADDR_ANY;
ServerSockAddr.sin_family := socket_family;
ServerSockAddr.sin_port := SocketHtons( wServerPort );
iOprRet := SocketBind( hSocket , ADR(ServerSockAddr) , SIZEOF(ServerSockAddr));
IF 0 = iOprRet THEN
SocketFdZero( ADR(FdSet) );
SocketFdSet( hSocket , ADR(FdSet) );
IF hSocket > maxFd THEN
maxFd := hSocket;
END_IF;
ELSE
SocketClose( hSocket );
hSocket := -1;
END_IF;
END_IF;
END_IF;
(* 数据接收处理 *)
IF hSocket >= 0 THEN
tmSlect.tv_sec := 0;
tmSlect.tv_usec := 10000;
FdSetRun := FdSet;
diReady := SocketSelect( maxFd + 1 , ADR(FdSetRun) , pSetTemp , pSetTemp , ADR(tmSlect) );
IF diReady > 0 THEN
IF SocketFdIsSet( hSocket , ADR(FdSetRun) ) THEN
diRecvedLen := SocketRecvfrom( hSocket , ADR(arrRecv) , SIZEOF(arrRecv) , dwFlags , ADR(SockAddrRecv), ADR(diSockAddrSize));
IF diRecvedLen > 0 THEN
dwRecvedTotalLen := dwRecvedTotalLen + diRecvedLen;
(* 将接收到的数据原封不动的返回 *)
SockAddrSend.sin_addr.addr := SockAddrRecv.sin_addr.addr;
SockAddrSend.sin_family := SOCKET_AF_INET;
SockAddrSend.sin_port := SockAddrRecv.sin_port;
diSentLen := SocketSendto( hSocket , ADR(arrRecv) , diRecvedLen , dwFlags , ADR(SockAddrSend) , SIZEOF(SockAddrSend));
IF diSentLen > 0 THEN
dwSentTotalLen := dwSentTotalLen + diSentLen;
ELSE
diLastError := GetLastError();
END_IF;
END_IF;
END_IF;
END_IF;
END_IF;
(* 关闭服务器 *)
IF bServerClose THEN
bServerClose := FALSE;
SocketFdClr( hSocket , ADR(FdSet) );
SocketClose( hSocket );
hSocket := -1;
END_IF;