网络编程socket相关操作

Socket

socket

打开一个网络连接

int socket (int family , int type ,int protocol)

family :协议族 , type : 套接字类型 , protocol :协议类型常值
套接字描述符sockfd

famliy : AF_INET(IPv4) AF_INET6(IPv6) AF_LOCAL AF_ROUTE
type : SOCK_STREAM(字节流套接字) SOCK_DGRAM(数据报套接字) SOCK_SEQPACKET(有序分组套接字) SOCK_RAW(原始套接字)
protocol : IPPROTO_TCP(TCP传输协议) IPPROTO_UDP(UDP传输协议) IPPROTO_SCTP(SCTP传输协议)

connect

TCP客户用connect来建立与TCP服务器的链接

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

sockfd : 套接字描述符 , addr : 指向套接字地址结构的指针 , addrlen : 该结构的大小
成功为0 , 出错则为-1

bind

把一个本地协议地址赋予一个套接字(协议地址是32位的IPv4地址或128位的IPv6地址与TCP或UDP的端口号的组合等)–>(绑定一个端口到套接字)
服务器在启动时捆绑它众所周知的端口。如果一个TCP客户或服务器未曾调用bind绑定一个端口,当调用connect或listen时,内核就要为相应套接字选一个临时端口。

int bind (int sockfd, const struct sockaddr * myaddr, socklen_t addrlen);

sockfd : 套接字描述符 , myaddr : 指向特定协议地址地址结构的指针 , addrlen : 该结构的大小
输出 成功为0 , 出错则为-1

listen

本函数通常应该在调用socket和bind之后,并且在accept之前
作用 : listen仅由TCP调用
(1)把一个未连接的套接字转换为一个被动套接字
(2)本函数的第二个参数规定了内核应该为相应套接字排队的最大连接个数

int listen (int sockfd, int backlog);

sockfd : 套接字描述符 , backlong : 相应套接字排队的最大连接个数
输出 成功为0 , 出错则为-1

accept

由TCP服务器调用,用于从已完成链接队列队头返回下一个已完成的链接

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

sockfd : 套接字描述符 , cliaddr和addrlen用来返回已连接的对端进程(客户)的协议地址
输出 成功为已连接套接字描述符 , 出错则为-1

accept成功,那么其返回值是由内核自动生成的一个全新描述符,代表与所返回客户的TCP链接

shudown

可以半关闭链接

int shutdown(int sockfd , int howto)

getsockopt setsockopt

获取和设置影响套接字的选项

int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);

sockfd: 必须指向一个打开的套接字描述符,level(级别)指定系统中解析选项的代码或为通用套接字代码,或为某个特定于协议的代码(例如IPv4、IPv6、TCP或SCTP)
level:协议层次
SOL_SOCKET 套接字层次
IPPROTO_IP ip层次
IPPROTO_TCP TCP层次
option_name:选项的名称(套接字层次)
SO_BROADCAST 是否允许发送广播信息
SO_REUSEADDR 是否允许重复使用本地地址
SO_SNDBUF 获取发送缓冲区长度
SO_RCVBUF 获取接收缓冲区长度
SO_RCVTIMEO 获取接收超时时间
SO_SNDTIMEO 获取发送超时时间
optval: 用于接收选项值 , 是一个指向某个变量(optval)的指针,setsockopt从optval中取得选项代设置的新值,getsockopt则把已获取的选项当前值存放到*optval中。*optval的大小由最后一个参数指定。
option_len:value的长度

getsockname getpeername

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

用于获取套接字本地/对端地址信息的函数。它允许程序检索与已绑定到特定套接字上的本地IP地址和端口号。

sockfd:标识要查询的套接字文件描述符。
addr:指向一个struct sockaddr类型的缓冲区指针,该缓冲区将填充套接字的本地地址信息(由于储存接受的信息)。
addrlen:在调用前,应设置为addr缓冲区的大小;在函数返回时,将包含实际存储在addr中的字节数。

unix域

sockpair

socketpair函数创建两个随后连接起来的套接字。本函数仅仅适应于unix域套接字

#include 
 
int socketpair(int family,int type,int protocol,int sockfd[2]);

family参数必须为AFLOCAL,protocol参数必须为0.type参数既可以是SOCKSTREAM。要创建的两个套接字描述符作为sockfd[0]和sockfd[1]返回

io

send recv

send 用于发送数据到已连接套接字的函数。它主要用于面向连接的协议,如TCP。
recv 主要用于面向连接的协议如TCP。它从指定的套接字读取数据,并将其存储在用户提供的缓冲区中。

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

sockfd:标识要发送数据的已连接套接字文件描述符。
buf:指向包含待发送数据的缓冲区指针。
len:指定要发送的数据量(以字节为单位)。
flags:可选标志,控制发送操作的行为。常见的标志包括:
MSG_OOB:发送带外数据。
MSG_DONTROUTE:不使用路由表,直接发送到网络接口。
在大多数情况下,此参数设置为0,表示使用默认行为。

返回值:
如果成功发送了所有数据,则返回实际发送/接受的字节数,可能小于请求发送的字节数。
若发生错误,返回-1,并将errno设置为相应的错误代码。

sendmsg recvmsg

sendmsg()允许程序以消息的形式同时发送多个缓冲区的数据,并可以附带控制信息。这个函数通常用于需要更多灵活性和功能的网络通信场景,如一次性发送多个独立的数据块或者传递协议相关的附加控制信息。
recvmsg()它允许程序以消息的形式从套接字接收数据,并可以获取与接收到的数据相关的控制信息。这个函数常用于需要处理多个缓冲区或底层协议控制信息的情况。

ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

struct msghdr {
    void         *msg_name;       // 指向目标地址结构的指针,对于接收操作是来源地址,在某些情况下可以为NULL
    socklen_t     msg_namelen;    // 目标地址结构的长度
    struct iovec *msg_iov;        // 指向iovec结构数组的指针,每个iovec定义了一个缓冲区和其长度
    int           msg_iovlen;     // iov数组中的元素个数
    void         *msg_control;    // 指向辅助控制信息的缓冲区的指针,包含与消息相关的底层协议控制信息
    socklen_t     msg_controllen; // 控制信息缓冲区的长度
    int           msg_flags;      // 返回值标志,由recvmsg()设置,表示消息接收的状态
};

struct iovec {
    void  *iov_base;   // 指向缓冲区起始位置的指针
    size_t iov_len;    // 缓冲区的长度(以字节为单位)
};

sockfd:标识要发送数据的已连接或未连接套接字文件描述符。
msg:指向一个 struct msghdr 结构体的指针,该结构体包含了待发送的消息的所有信息:
flags:可选标志,与 send() 或 sendto() 函数中的 flags 参数类似,控制发送操作的行为。

使用:

    char message1[] = "Hello, ";
    char message2[] = "world!";
    struct iovec iov[2];
    iov[0].iov_base = message1;
    iov[0].iov_len = strlen(message1);
    iov[1].iov_base = message2;
    iov[1].iov_len = strlen(message2) + 1; // 包括终止的空字符

    struct msghdr msg;
    memset(&msg, 0, sizeof(msg));
    msg.msg_iov = iov;
    msg.msg_iovlen = 2;

    ssize_t bytes_sent = sendmsg(sockfd, &msg, 0);

sendto recvfrom

读取数据,发送数据类似于read,write

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

sockfd:标识要从中接收数据的未连接套接字文件描述符。
buf:指向一个缓冲区的指针,接收的数据将被存放在这个缓冲区中。
len:指定缓冲区的大小,即最多可以接收多少字节的数据。
flags:可选标志,控制接收操作的行为。例如,MSG_PEEK可以让数据保留在接收缓冲区中不被移除,MSG_WAITALL则请求接收所有请求的数据量。
src_addr:指向一个 struct sockaddr 类型的缓冲区,用来存放发送/接受数据的源地址信息。
addrlen:在调用前,应该设置为 src_addr 缓冲区的大小;函数返回后,会更新为实际存储的地址结构体的长度。

输出 成功为读或者写的字节数 , 出错则为-1

    char message[] = "Hello, UDP!";
    size_t len = strlen(message) + 1; // 包括终止的空字符

    struct sockaddr_in dest_addr;
    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    inet_pton(AF_INET, "192.168.1.100", &dest_addr.sin_addr); // 目标IP地址
    dest_addr.sin_port = htons(12345); // 目标端口号

    ssize_t bytes_sent = sendto(sockfd, message, len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));

你可能感兴趣的:(Linuxc++,网络,c++,c语言)