Linux C语言 30-套接字操作
Linux C语言 30-套接字操作
本节关键字:C语言 网络通信、套接字操作、TCP、UDP、服务端、客户端
相关C库函数:socket, bind, listen, accept, setsockopt, recv, send, recvfrom, sendto, close
什么是网络通信?
通信是人与人之间通过某种媒体进行的信息交流与传递。网络是用物理链路将各个孤立的工作站或主机相连在一起,组成的数据链路。通信网络是指将各个孤立的设备进行物理连接,实现人与人,人与计算机,计算机与计算机之间进行信息交换的链路,从而达到资源共享和通信的目的。
在编程过程中,设计网络通信时一般只考虑两个对象:“服务端”和“客户端”。服务端与客户端可以存活于相同主机,也可以存活在不同主机。在服务端与客户端的通信中需要使用到套接字。那么套接字(socket)到底什么是呢?
什么是套接字?
“socket”直译为“插座”。从抽象层面看,服务端就好比插座,客户端就好比插头,二者之间是紧密联系的。套接字分为三类:
- 流套接字(SOCK_STREAM)
流套接字用于提供面向连接、可靠的数据传输服务,该服务保证数据能够实现无差错、无重复发送,并按照顺序接受。流套接字之所以能偶实现可靠的数据服务,原因在于使用了TCP传输控制协议。 - 数据报套接字(SOCK_DGRAM)
数据包套接字提供了一种无连接的服务,该服务不能保证数据传输的可靠性,数据有可能在传输过程中丢失或者出现数据重复,且无法保证顺序的接受数据。数据报套接字使用UDP进行数据传输。 - 原始套接字(SOCK_RAW)
原始套接字允许对较低层次的协议直接访问,常用于检验新的协议实现,或者访问现有服务中配置的新设备,因为器可以自如控制Window下的多种协议,能够对网络地城的传输机制进行控制,所以可以应用原始套接字来操纵网络层和传输层应用。如:通过原始套接字接受发向本机的ICMP、IGMP,或者接受TCP/IP栈不能处理的IP包。
套接字通常由三个参数构成:IP地址、端口号和传输层协议。在C语言中主要有两类套接字通信:“TCP通信”和“UDP通信”。在实际编程时,通常会使用struct sockaddr和struct sockaddr_in两种数据类型来保存套接字信息。
// 大部分情况作为bind、connect、recvfrom、sendto等函数的参数进行传递,指明地址信息。在实际编程中,一般不对此结构体进行直接操作,而是使用sockaddr_in代替。
struct sockaddr
{sa_family_t sa_family; // 地址族char sa_data[14]; // 地址和端口号
};struct sockaddr_in
{short int sin_family; // 地址族unsigned short int sin_port; // 端口号struct in_addr sin_addr; // 地址unsigned char sin_zero[8]; // 8字节数组,全为0,该字节数组的作用是为了让两种数据结构大小相同而保留的空字节
};// 两种数据结构中,地址族都占用两个字节,常见的地址族为:AF_INET、AF_INET6、AF_LOCAL。
// 值得注意的是网络编程中的字节序问题,建议使用C库中的相关函数对端口和地址进行字节序处理:
#include <stdio.h>
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;uint16_t htons(uint16_t bost16bit); // 将一个主机字节顺序的无符号短整型数转换成网络字节顺序
uint32_t htonl(uint32_t bost32bit); // 将一个主机字节顺序的无符号长整型数转换成网络字节顺序
uint16_t ntons(uint16_t net16bit); // 将一个无符号短整型数从网络字节顺序转换为主机字节顺序
uint32_t ntonl(uint32_t net32bit); // 将一个无符号长整型数从网络字节顺序转换为主机字节顺序
C语言网络编程之TCP通信
TCP通信相关库函数
TCP套接字参数设置
// 套接字参数设置
#include <sys/types.h>
#include <sys/socket.h>
// 设置套接字参数,成功返回0,失败返回-1并且设置error
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
// 获取套接字参数,成功返回0,失败返回-1并且设置error
int getsockopt(int sockfd, int level, int optname, const void *optval, socklen_t *optlen);
/*
sockfd: 由socket()函数返回的套接字描述符
level: SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP、IPPROTO_IPV6
optname: 可用选项 SO_DEBUF、SO_DONTROUTE、SO_KEEPALIVE、SO_LINGER、SO_OOBINLINE、
SO_RCVBUG、SO_RCVLOWAT、SO_REUSEADDR、SO_SNDBUF、SO_SNDLOWAT、TCP_MAXSEG等
optval: 指针,指向存放选项值的缓冲区
optlen: optval缓冲区的长度
*/
// 设置端口复用(必须在bind()函数之前设置),对应重启程序后出现端口绑定失败的场景
int reuse = 1; // 默认为0,不启用端口复用
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&reuse, sizeof(int));// 设置收发超时时间,对应由于网络原因导致send()或recv()执行异常而发生阻塞的场景
int timeout = 1000; // 1秒
// 发送时限
setsockopt(socket, SOL_S0CKET, SO_SNDTIMEO, (const void*)&timeout, sizeof(int));
// 接收时限
setsockopt(socket, SOL_S0CKET, SO_RCVTIMEO, (const void*)&timeout, sizeof(int));// 设置缓冲区大小,对应由于缓冲区爆满导致send()函数执行异常而发生阻塞的场景
// 值得注意的是:并不是说你设置的多大,系统就会设置多大,系统一般会将我们设置的缓冲区大小加倍,并且不得小于tcp的接收缓冲区和发送缓冲区设置的默认最小值。
// TCP有发送缓冲区和接收缓冲区,但是UDP因为是不可靠的,它没有确认重传机制,不保存应用程序数据的副本,所以是没有发送缓冲区的,但是UDP有接收缓冲区。
int buflen = 32*1024; // 32K
// 接收缓冲区
setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (const void*)&buflen, sizeof(int));
// 发送缓冲区
setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (const void*)&buflen, sizeof(int));// 优化由系统缓冲区到socket缓冲区拷贝过程对程序性能的影响
int zero=0;
setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (const void*)&zero, sizeof(int));
setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (const void*)&zero, sizeof(int));// 在UDP数据通信时,设置socket发送的数据具有广播特性
int broad = 1;
setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const void*)&broad, sizeof(int));// 设置心跳检测
int opt = 1;
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeog(int));// 延迟接收,当接收到第一条数据之后再创建连接。对于http类非交互式的服务器很有意义,可以防御空连接攻击
int val = 5;
setsockopt(socket, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(int));
TCP服务端和客户端共用
// TCP服务端和客户端共用
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>// 创建一个指定类型的套接字,成功返回套接字,失败返回-1并设置错误码error
// domain 指定通信域,选择用于通信的协议族,这些协议族在<sys/socket.h>中定义
// 名称 描述 说明
// AF_UNIX, AF_LOCAL Local communication 本地通信协议
// AF_INET IPv4 Internet protcaols IPv4互联网协议
// AF_INET6 IPv6 Internet protcaols IPv6互联网协议
// AF_IPX IPX - Novell protocols IPX-Novell协议
// AF_NETLINK Kernel user interface device 内核用户接口设备协议
// AF_X25 ITU-T X.25 / ISO-8202 protocal ITU-T X.25/ISO-82208协议
// AF_AX25 Amater redio AX.25 protocol 业余无线电AX.25协议
// AF_ATMPVC Access to raw ATM PVCs 访问原始ATM PVC
// AF_APPLETALK Appletalk 由Apple公司创建的一组网络协议
// AF_PACKET Low level packet interface 低级数据包接口
// type 套接字类型
// SOCK_STREAM 提供有序、可靠、双向、基于连接的字节流,可以支持带外数据传输机制
// SOCK_DGRAM 支持数据报(固定最大长度的无连接、不可靠的消息)
// SOCK_SEQPACKET 为固定最大长度的数据报提供一条有序、可靠、双向连接的数据传输路径;消费者需要用每个输入系统调用读取这个数据报
// SOCK_RAW 提供原始网络协议访问
// SOCK_RDW 提供不保证排序的可靠数据报层
// SOCK_PACKET 已过时,不应在新程序中使用
// protocol 指定与套接字一起使用的特定协议。在给定的协议族中,通常只有一个协议支持特定的套接字类型,这种情况下protocol可以为0;也有存在很多协议的情况,此时protocol必须指定特定的协议
// error 错误码
// EACCES 创建指定类型和/或协议的套接字的权限被拒绝。
// EAFNOSUPPORT 该实现不支持指定的地址系列。
// EINVAL 未知协议或协议系列不可用。类型中的标志无效。
// EMFILE 进程文件表溢出。已达到系统对打开文件总数的限制。
// ENOBUFS or ENOMEM 可用内存不足。在释放足够的资源之前,无法创建套接字。
// EPROTONOSUPPORT 此域中不支持协议类型或指定的协议。
int socket(int domain, int type, int protocol);// recv()从已连接的套接字读取数据,与src_addr为NULL的recvfrom()相同
// 成功返回读取消息的长度,如果消息太长导致无法放入所提供的缓冲区,则可能会丢弃多余的字节,具体取决于接收消息的套接字类型
// 如果套接字上没有可读的消息,recv将阻塞等待消息到达。若套接字是非阻塞的将返回-1,此时error被设置为EAGIN或EWOULDBLOCK
// 注意:读取套接字通常会返回任何可用的数据,而不是等待到请求的全部数据,这就导致可能出现数据包分帧的情况
// flags参数一般设置为0,也可通过对以下一个或多个值进行“或”运算形成:
// MSG_CMSG_CLOEXEC 使用SCM_RIGHTS操作,为通过UNIX域文件描述符接收的文件描述符设置关闭exec标志。
// MSG_DONTWAIT 启用非阻塞操作;如果操作将被阻止,则调用将失败,并显示错误EAGAIN或EWOULDBLOCK(也可以使用带有F_SETFL的O_NONBLOCK标志来启用fcntl(2))。
// MSG_ERRQUEUE 此标志指定应从套接字错误队列接收排队的错误。错误在类型取决于协议的辅助消息中传递(对于IPv4IP_RECVERR)。用户应提供足够大小的缓冲区。
// MSG_OOB 该标志请求接收在正常数据流中不会接收到的带外数据。一些协议将加急数据放在正常数据队列的头部,因此该标志不能与此类协议一起使用。
// MSG_PEEK 此标志使接收操作从接收队列的开头返回数据,而不从队列中删除该数据。因此,随后的接收呼叫将返回相同的数据。
// MSG_TRUNC (since Linux 2.2) 对于raw(AF_PACKET)、Internet数据报(自Linux 2.4.27/2.6.8起)、netlink(自Linux 2.6.22起)和UNIX数据报(从Linux 3.4起)套接字:返回数据包或数据报的实际长度,即使它比传递的缓冲区长。未针对UNIX域(UNIX(7))套接字实现。有关与Internet流套接字一起使用的信息,请参阅tcp(7)。
// MSG_WAITALL (since Linux 2.2) 该标志请求操作块,直到完全请求得到满足为止。然而,如果捕捉到信号、发生错误或断开连接,或者下一个要接收的数据与返回的数据类型不同,则调用返回的数据可能仍然少于请求的数据。
// MSG_EOR 表示记录结束;返回的数据完成了一个记录(通常与类型为SOCK_SEQPACKET的套接字一起使用)。
// MSG_TRUNC 指示数据报的尾部被丢弃,因为数据报大于所提供的缓冲区。
// MSG_CTRUNC 指示一些控制数据由于缓冲器中用于辅助数据的空间不足而被丢弃。
// MSG_OOB 以指示已接收到加急或带外数据。
// MSG_ERRQUEUE 指示未接收到任何数据,但接收到来自套接字错误队列的扩展错误。
// error 错误码类型
// EAGAIN或者EWOULDBLOCK 套接字设置为非阻塞,但所请求的操作需要阻塞;套接字被标记为非阻塞,接收操作将被阻塞,或者设置了接收超时,并且在接收数据之前超时已过期。POSIX.1-2001允许在这种情况下返回任何一个错误,并且不要求这些常量具有相同的值,因此便携式应用程序应该检查这两种可能性。
// EBADF 指定了非法套接字描述符
// ECONNREFUSED 远程主机拒绝允许网络连接(通常是因为它没有运行请求的服务)
// EFAULT 参数指定的用户地址空间非法
// EINTR 接收到信号
// EINVAL 传递的参数非法
// ENOMEM 没有可用内存
// ENOTCONN 套接字与面向连接的协议相关联,并且尚未连接
// ENOTSOCK 参数sockfd不是一个套接字
ssize_t recv(int sockfd, void *buf, size_t len, int flags);// send()从已连接的套接字读取数据。成功返回读取的字节数,失败返回-1并设置error
// flags一般为0,也可包含下列标志:
// MSG_CONFIRM (仅用于Linux 2.3以上版本)通知链路层发生了转发过程:得到了另一端的成功应答.如果链路层没有收到通知,它将按照常规探测网络上的相邻主机(比如通过免费arp).只能用于SOCK_DGRAM和SOCK_RAW类型的套接字,且仅对IPv4和IPv6有效.详情参见 arp(7)
// MSG_DONTROUTE 在送出分组时不使用网关,只有直接连接在网络上的主机才能接收到数据。这个标志通常仅用于诊断和路由程序,路由的协议族才能使用这个标志;套接字不可以。
// MSG_DONTWAIT 使用非阻塞式操作;如果操作需要阻塞,将返回 EAGAIN 错误(也可以用 F_SETFL fcntl(2) 设置 O_NONBLOCK 实现这个功能.)
// MSG_EOR (since Linux 2.2)终止记录(当支持此概念时,如SOCK_SEQPACKET类型的套接字)。// MSG_MORE (Since Linux 2.4.4) 呼叫者还有更多数据要发送。此标志与TCP套接字一起使用,以获得与TCP_CORK套接字选项相同的效果(请参阅TCP(7)),不同之处在于此标志可以在每次调用的基础上设置。自Linux 2.6以来,UDP套接字也支持此标志,并通知内核将设置了此标志的调用中发送的所有数据打包为单个数据报,该数据报仅在执行未指定此标志的呼叫时发送。(另请参阅UDP(7)中描述的UDP_CORK套接字选项)。
// MSG_NOSIGNAL 当流式套接字的另一端中断连接时不发送 SIGPIPE 信号,但仍然返回 EPIPE 错误.
// MSG_OOB在支持此概念的套接字上发送带外数据(例如,类型为SOCK_STREAM);底层协议还必须支持带外数据。
// error 错误码类型
// EACCES (对于由路径名标识的UNIX域套接字)目标套接字文件的写入权限被拒绝,或者路径前缀的某个目录的搜索权限被拒绝。(对于UDP套接字)试图将其发送到网络/广播地址,就好像它是单播地址一样。
// EAGAIN或者EWOULDBLOCK 套接字设置为非阻塞,但所请求的操作需要阻塞
// EBADF 指定了非法套接字描述符
// ECONNRESET 对等方重置连接。
// EDESTADDRREQ 套接字不是连接模式,并且没有设置对等地址。
// EFAULT 参数指定的用户地址空间非法
// EINTR 接收到信号
// EINVAL 传递的参数非法
// EISCONN 连接模式套接字已连接,但指定了收件人。(现在,要么返回此错误,要么忽略收件人规范。)
// EMSGSIZE 消息长度越界,套接字类型要求以原子方式发送消息,而要发送的消息的大小使得这不可能实现
// ENOBUFS 网络接口输出队列已满,这通常表明接口已停止发送,也有可能是暂时性的拥挤(这不会发生在linux下,当设备队列溢出时数据报只是被简单的丢弃)
// ENOMEM 没有可用内存
// ENOTCONN 套接字未连接,也未给定目标
// ENOTSOCK 参数sockfd不是一个套接字
// EOPENOTSUPP flags参数中的某些位不适合套接字类型
// EPIPE 连接套接字的本地端已关闭,这种情况下进程还会接收到SIGPPIPE信号,除非设置了MSG_NONSIGNAL
ssize_t send(int sockfd, const void *buf, size_t len, int flags);// 关闭文件描述符
int close(int fd);
TCP服务端使用
// TCP服务端使用
#include <sys/types.h>
#include <sys/socket.h>
// 为套接字sockfd指定本地地址addr,传统的叫法是给一个套接字分配一个名字。使用socket()函数创建一个套接字时,它存在一个地址空间(地址表),但还没有给它分配一个名字
// 成功返回0,失败返回-1并设置错误码error
// error 错误码类型:
// EBADF sockfd 不是一个合法套接字描述符.
// EINVAL 套接字已经绑定到一个地址.这一条在以后会有所改变: 具体参见 linux/unix/sock.c
// EACCES 地址受保护,用户不是系统管理员.
// ENOTSOCK参数是文件描述符,不是一个套接字.
// 下列错误适用于UNIX域 (AF_UNIX) 套接字.
// EINVAL 地址长度 addrlen 错误,或者套接字不在 AF_UNIX 族.
// EROFS 套接字节点位于只读文件系统.
// EFAULT 参数addr 指向用户无权访问的地址空间.
// ENAMETOOLONG参数addr 长度超范围.
// ENOENT 文件不存在.
// ENOMEM 内核存储空间不足.
// ENOTDIR指定路径不是一个目录.
// EACCES 指定路径拒绝访问.
// ELOOP 在解析 my_addr 时发现过多符号连接.
int bind(int sockfd, const struct sockaddr *addr, socklen_t addlrlen);// 在接收连接之前,首先要使用socket()创建一个套接字,然后调用listen()使其能够自动接收到来的连接并且为连接队列指定一个长度限制.之后就可以使用accept()接收连接.listen()调用仅适用于SOCK_STREAM或者SOCK_SEQPACKET类型的套接字.
// 成功返回0,错误返回-1并设置错误码error
// 参数backlog指定未完成连接队列的最大长度.如果一个连接请求到达时未完成连接队列已满,那么客户端将接收到错误ECONNREFUSED.或者,如果下层协议支持重发,那么这个连接请求将被忽略,这样客户端在重试的时候就有成功的机会.
// error 错误码类型:
// EBADF 参数 s 不是合法的描述符.
// ENOTSOCK参数 s 不是一个套接字.
// EOPNOTSUPP套接字类型不支持 listen 操作.
int listen(int sockfd, int backlog);// accept()函数用于基于连接的套接字(SOCK_STREAM, SOCK_SEQPACKET 和 SOCK_RDM).它从未完成连接队列中取出第一个连接请求,创建一个和参数sockfd属性相同的连接套接字,并为这个套接字分配一个文件描述符,
然后以这个描述符返回.新创建的描述符不再处于监听状态.原套接字socket不受此调用的影响.注意任意一个文件描述符标志(任何可以被fcntl以参数 F_SETFL 设置的值,比如非阻塞式或者异步状态)不会被accept. 所继承.
// 参数sockfd是以socket()函数创建,用bind()函数绑定到一个本地地址,并且在调用了listen()函数进行监听的套接字.
// 参数addr是一个指向结构sockaddr的指针.这个结构体以连接实体地址填充.所谓的连接实体,就是众所周知的网络层.参数 addr 所传递的真正的地址格式依赖于所使用的套接字族.(参见 socket(2) 和各协议自己的手册页).
// 参数addrlen是一个实时参数: 它的大小应该能够足以容纳参数
addr 所指向的结构体;在函数返回时此参数将以字节数表示出返回地址的 实际长度.若 addr 使用NULL作为参数,addrlen将也被置为NULL.
// 如果队列中没有未完成连接套接字,并且套接字没有标记为非阻塞式, accept 将阻塞直到一个连接到达.如果一个套接字被标记为非阻塞式而队列 中没有未完成连接套接字, accept 将返回EAGAIN.
// 成功返回一个新的套接字,失败返回-1并设置错误码error
// error 错误码类型:
// EAGAIN或者EWOULDBLOCK 套接字被标记为非阻塞,且当前没有可接收的连接.
// EBADF 描述符非法.
// ENOTSOCK描述符指向一个文件,而不是一个套接字.
// EOPNOTSUPP作为参数的套接字不是 SOCK_STREAM.类型
// EFAULT 参数 addr 不在用户可写地址空间之内.
// EPERM 防火墙规则禁止连接.
// ENOBUFS,ENOMEM 没有足够内存. 这个错误一般来说意味着内存分配受套接字缓冲区所限, 而不是没有系统内存.
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
TCP客户端使用
// TCP客户端使用
#include <sys/types.h>
#include <sys/socket.h>
// 将文件描述符sockfd引用的套接字连接到addr指定的地址。addrlen指定addr的大小,addr中地址的格式由套接字sockfd的地址空间决定
// 如果套接字sockfd的类型是SOCK_DGRAM,那么addr是默认情况下发送数据报的地址,也是接收数据报的唯一地址。如果套接字的类型是SOCK_STREAM或SOCK_SEQPACKET,则此调用将尝试连接到绑定到addr指定地址的套接字。
// 通常,基于连接的协议套接字可能只成功connect()一次;无连接协议套接字可以多次使用connect()来更改其关联。无连接套接字可以通过连接到sockaddr的sa_family成员设置为AF_UNSPEC(自内核2.2以来在Linux上受支持)的地址来解除关联。
// 成功返回0,失败返回-1并设置错误码error
// error 错误码类型:
// EACCES 对于由路径名标识的UNIX域套接字:套接字文件的写入权限被拒绝,或者路径前缀中某个目录的搜索权限被拒绝。(另请参见path_resolution(7)。)
// EACCES, EPERM 用户尝试在未启用套接字广播标志的情况下连接到广播地址,或者由于本地防火墙规则,连接请求失败。
// EADDRINUSE 本地地址已在使用中。
// EAFNOSUPPORT 传递的地址的sa_family字段中没有正确的地址族。
// EADDRNOTAVAIL 请求的接口不存在,或者请求的地址不是本地地址。
// EALREADY 套接字是非阻塞的,以前的连接尝试尚未完成。
// EBADF 文件描述符不是描述符表中的有效索引。
// ECONNREFUSED 没有人在监听远程地址。
// EFAULT 套接字结构地址在用户的地址空间之外。
// EINPROGRESS 套接字是非阻塞的,无法立即完成连接。可以通过选择写入套接字来select()或poll()以完成。在select()指示可写入性后,使用getsockopt(2)读取SOL_SOCKET级别的SO_ERROR选项,以确定connect()是否成功完成(SO_ERROR为零)或未成功(SO_ERROR是此处列出的常见错误代码之一,解释了失败的原因)。
// EINTR 系统调用被捕获的信号中断;参见信号(7)。
// EISCONN 套接字已连接
// ENETUNREACH 网络无法访问
// ENOTSOCK 文件描述符未与套接字关联。
// ETIMEDOUT 尝试连接时超时。服务器可能太忙,无法接受新连接。请注意,对于IP套接字,当服务器上启用syncookies时,超时时间可能会很长。
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
TCP通信服务端例程
Linux C语言 31-网络编程之TCP例程
TCP通信客户端例程
Linux C语言 31-网络编程之TCP例程
C语言网络编程之UDP通信
UDP通信相关库函数
#include <sys/types.h>
#include <sys/socket.h>
// UDP服务端和客户端共用
// 同TCP部分解释
int socket(int damain, int type, int protocol);
// 从套接字接收消息和读取数据,套接字可以是面向连接的,也可以不是面向连接的
// 如果参数src_addr不为NULL,并且底层协议提供了源地址,则会填写此源地址。当src_addr为NULL时,则不填写任何内容;在这种情况下,不使用addrlen,也应该为NULL。
// 如果提供的缓冲区太小,则会截断返回的地址;在这种情况下,addrlen将返回一个大于提供给调用的值。
// 如果src_addr为NULL,使用方法和recv()一样
// 成功返回读取的字节数,失败返回-1,并设置错误码error(同TCP部分解释)
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);// 将消息传输到另一个套接字,如果在连接模式(SOCK_STREAM、SOCK_SEQPACKET)套接字上使用sendto(),则参数dest_addr和addrlen将被忽略(当它们不是NULL和0时,可能会返回错误EISCONN),而当套接字未实际连接时,则会返回错误ENOTCONN。否则,目标的地址由dest_addr给定,addrlen指定其大小。对于send()和sendto(),消息位于buf中,长度为len
// 成功返回发送字节数,失败返回-1并设置错误码error,错误码说明同TCP部分解释
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);#include <unistd.h>
// 关闭套接字
int close(int fd);// UDP服务端使用
// 同TCP部分解释
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
UDP通信服务端例程
Linux C语言 32-网络编程之UDP例程
UDP通信客户端例程
Linux C语言 32-网络编程之UDP例程
相关文章:

Linux C语言 30-套接字操作
Linux C语言 30-套接字操作 本节关键字:C语言 网络通信、套接字操作、TCP、UDP、服务端、客户端 相关C库函数:socket, bind, listen, accept, setsockopt, recv, send, recvfrom, sendto, close 什么是网络通信? 通信是人与人之间通过某种…...

RPC和REST对比
RPC和REST对比 参考学习 RPC 和 REST 之间有什么区别? 当我们对比RPC和REST时,其实是在对比RPC风格的API和REST风格的API,后者通常成为RESTful API。 远程过程调用(RPC)和 REST 是 API 设计中的两种架构风格。API …...

外包干了2年,技术退步明显。。。
前言 简单的说下,我大学的一个同学,毕业后我自己去了自研的公司,他去了外包,快两年了我薪资、技术各个方面都有了很大的提升,他在外包干的这两年人都要废了,技术没一点提升,学不到任何东西&…...

深度学习——第1章 深度学习的概念及神经网络的工作原理
1.1 序言——探索智能机器 千百年来,人类试图了解智能的机制,并将它复制到思维机器上。 人类从不满足于让机械或电子设备帮助做一些简单的任务,例如使用滑轮吊起沉重的岩石,使用计算器做算术。 人类希望计算机能够自动化执行更…...

爬虫爬取百度图片、搜狗图片
通过以下代码可以爬取两大图片网站(百度和搜狗)的图片,对于人工智能、深度学习中图片数据的搜集很有帮助! 一、爬取百度图片 该代码可以爬取任意百度图片中自定义的图片: import requests import re import time imp…...

Android Camera2使用
一 简介 1.1 Camera API: 这是旧版本的相机API,也称为Camera1 API。它提供了较简单的使用方式,适用于旧版Android设备。但它存在一些限制,如性能不佳、操作复杂等 1.2 Camera2 API: 这是新版本的相机API࿰…...

IOS/安卓+charles实现抓包(主要解决证书网站无法打开问题)
安装 官网下载 https://www.charlesproxy.com/latest-release/download.do 安装charles文档 流程 上述链接解决下图问题 使用介绍 Charles介绍 上述链接看一至三即可,了解首页各个按钮的作用 charles全面使用教程及常见功能详解(较详细)…...

七、Lua字符串
文章目录 一、字符串(一)单引号间的一串字符(二)local str "Hello, "(三)[[ 与 ]] 间的一串字符(四)例子 二、字符串长度计算(一)string.len&…...

0基础学java-day13
一、包装类 1. 包装类的分类 1) 针对八种基本数据类型相应的引用类型【对象】—包装类 2) 有了类的特点,就可以调用类中的方法。 3) 如图: 2 包装类和基本数据的转换 3 案例演示 Integer01.java package com.hspedu.wrapper;/*** author 林然* version 1.0*/ p…...

好题记录:
好题记录: 1:2:3:三级目录 1: 下面代码的结果是:( ) 下面代码的结果是:( )#include <stdio.h> int main() {int arr[] {1,2,3,4,5};short *p (short*)arr;int i …...

web前端之JavaScrip中的闭包
MENU 闭包--笔试-11defineReactive函数,利用闭包封装Object.defineProperty()闭包--节流函数--笔试-10闭包的定义JavaScript闭包的9大经典使用场景 闭包–笔试-11 function fun() { var n 9; // js 中强行给一个未声明的变量赋值,// 程序不会报错// 并…...

Windows下命令行启动与关闭WebLogic的相关服务
WebLogic 的服务器类型 WebLogic提供了三种类型的服务器: 管理服务器节点服务器托管服务器 示例和关系如下图: 对应三类服务器, 就有三种启动和关闭的方式。本篇介绍使用命令行脚本的方式启动和关闭这三种类型的服务器。 关于WebLogic 的…...

LeetCode Hot100 169.多数元素
题目: 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 方法一:哈希表 class Solution {public int…...

数据结构:堆的实现思路
我们之前写过堆的实现代码:数据结构:堆的实现-CSDN博客 这篇文章我们了解一下堆到底是如何实现的 1.堆向下调整算法 现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆 向下调…...

结合 DBSCAN 示例代码介绍 DBSCAN
前文为JoyT的科研之旅第一周——科研工具学习及论文阅读收获-CSDN博客 DBSCAN 介绍 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它能够识别出任意形状的簇,并有效地处理噪声…...

vscode 调试jlink
文章目录 软件使用说明1、启动GDB Server2、下载gdb3、vscode配置4、调试 软件 vscodejlink - (JLinkGDBServer.exe)gcc-arm-none-eabi-10-2020-q4-major (arm-none-eabi-gdb.exe) 使用说明 vscode通过TCP端口调用JLinkGDBServer通过jlink连接和操作设备,vscode不…...

微前端实战:打造高效、灵活的前端应用架构
文章目录 一、微前端简介二、微前端的优势1. 高度模块化2. 独立部署3. 易于扩展4. 技术栈无关5. 独立升级 三、微前端的原理四、微前端案例思路《微前端实战》编辑推荐内容简介作者简介目录前言/序言 随着互联网行业的快速发展,前端应用的规模和复杂度也在不断增加。…...

csv文件EXCEL默认打开乱码问题
这里讨论的问题是,当用记事本打开带有中文字符的csv正常时,用excel打开却是乱码。 简单概括就是:编码问题,windows的 excel打开csv文本文件时,默认使用的是系统内的ANSI,在中文环境下就是GB2312。如果写文件…...

C语言之实现贪吃蛇小游戏篇(2)
目录 🎇测试游戏test.c 🎇游戏头文件包含&函数声明snake.h 🎇游戏实现snake.c 🎇测试游戏test.c #define _CRT_SECURE_NO_WARNINGS 1 #include "snake.h" void test() {int ch 0;do{Snake snake { 0 };//创建…...

Comparator接口
Comparator接口 Comparator 是 Java 中用于比较对象的接口。它允许开发者实现自定义的比较逻辑,以用于对对象进行排序或者确定它们的顺序。 主要方法: Comparator 接口中包含一个抽象方法: int compare(T o1, T o2):用于比较两…...

SELinux refpolicy详解(9)
接前一篇文章:SELinux refpolicy详解(8) 三、refpolicy内容详解 上一回讲解了refpolicy源码根目录下的build.conf文件的前一部分内容。本回继续讲解其后一部分。 2. build.conf 文件路径:refpolicy源码根目录/build.conf。 文…...

零基础上手,秒识别检测,IDEA研究院发布全新T-Rex模型
目标检测作为当前计算机视觉落地的热点技术之一,已被广泛应用于自动驾驶、智慧园区、工业检测和卫星遥感等场景。开发者在研究相关目标检测技术时,通常需熟练掌握图像目标检测框架,如通用目标检测框架 YOLO 系列,旋转目标检测框架…...

python每日一题——20旋转图像
题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]]…...

云计算生成式 -给你不一样的音乐推荐新体验
目录 摘要: 正文: 一、亚马逊云与生成式 AI 结合的展望/总结 二、我用亚马逊云科技生成式 AI 产品打造了什么,解决了什么问题 三、未来云端技术发展趋势的见解 四、云端技术未来需要解决的问题 1、如何保护数据安全和隐私? …...

Zabbix 6.0部署+自定义监控项+自动发现与自动注册+部署zabbix代理服务器
Zabbix 6.0 Zabbix 6.0一、关于zabbix1、什么是zabbix2、zabbix工作原理3、zabbix 6.0 特性4、zabbix 6.0 功能组件 二、Zabbix 6.0 部署1、 部署 zabbix 服务端(1) 部署 Nginx PHP 环境并测试(2) 部署数据库(3) 编译安装 zabbix server 服务端(4) 部署 Web 前端,进…...

Docker 简介及其常用命令详解
Docker 简介及其常用命令详解 Docker 自推出以来,已成为开发和运维领域的重要工具。它简化了应用的部署、测试和分发过程,使得容器化技术成为现代软件开发的标准实践。本文将为您提供Docker的基础介绍以及其常用命令的详细讲解。 什么是Docker…...

基于PHP的高中生物学习平台
有需要请加文章底部Q哦 可远程调试 基于PHP的高中生物学习平台 一 介绍 此高中生物学习平台基于原生PHP开发,数据库mysql。系统角色分为用户和管理员。(附带参考设计文档) 技术栈:phpmysqlphpstudyvscode 二 功能 学生 1 注册/登录/注销 2 个人中心 …...

Git多库多账号本地SSH连接配置方法
Git多库多账号本地SSH连接配置方法 一、前言二、环境三、帮助文档四、多环境配置4.1 配置config文件 五、生成RSA秘钥对5.1 ssh秘钥位置5.2 生成秘钥对(公钥、私钥)5.3 添加公钥到GIT用户配置中 六 测试git是否可以使用七、总结 一、前言 在使用Git管理…...

爬虫学习-基础(HTTP原理)
目录 一、URL和URI 二、HTTP和HTTPS (1)HTTP (2)HTTPS (3)HTTP与HTTPS区别 (4)HTTPS对HTTP的改进:双问的身份认证 三、TCP协议 (1)TCP三次握手…...

Gazebo 中为地面和车轮添加摩擦属性
Gazebo 中为地面和车轮添加摩擦属性 Link friction properties not applied from URDF to Gazebo SDFormat Specification Adding friction to model wheels Gazebo中模型自行滑动(后溜)的原因探究 移动机器人在仿真时,一旦以较大的速度启动&…...