1-函数声明
函数声明
连接工作
服务器
1.socket函数
头文件:<sys/socket.h>
创建一个未被使用的socket,并进行初始化协议。
int socket(int domain, int type,int protocol); |
参数:
-
domain
:指定协议族AF_INET
表示IPv4协议族AF_INET6
表示IPv6协议族。
-
type
:指定套接字类型SOCK_STREAM
表示基于TCP协议的流式套接字SOCK_DGRAM
表示基于UDP协议的数据报套接字等。
-
protocol
:指定协议类型,在通常为0表示使用默认协议。IPPROTO_TCP
:TCP传输协议。IPPROTO_UDP
:UDP传输协议。IPPROTO_SCTP
:SCTP传输协议。IPPROTO_ICMP
:ICMP协议。IPPROTO_RAW
:原始IP数据包协议。IPPROTO_IP
:IP协议,通常用于在IPv4和IPv6之间进行区分。
函数返回值:为新建套接字的描述符。如果失败,将返回-1并设置errno变量。
2.bind函数
头文件:
将socket和服务器的地址绑定。
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen); |
参数:
-
sockfd
: -
myaddr
:指向一个标志ip和端口号的结构体。在为结构体赋值时使用sockaddr_in,使用时强转为该结构体类型。-
struct sockaddr_in { sa_family_t sin_family; // 协议族,始终为AF_INET in_port_t sin_port; // 端口号 struct in_addr sin_addr; // IPv4地址信息 char sin_zero[8]; // 未使用,填充0 };
* ```C++
servaddr.sin_family = AF_INET; // 协议族,在socket编程中只能是AF_INET。
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意ip地址。
//servaddr.sin_addr.s_addr = inet_addr("118.89.50.198"); // 指定ip地址。
servaddr.sin_port = htons(5051); // 指定通信端口。
-
-
addrlen
:第二个参数的大小,sizeof()
返回值:
-
0,成功
-
-1,失败
3.listen函数
将socket设置为监听模式。
int listen(int sockfd, int backlog); |
参数:
-
sockfd
:socket -
backlog
:等待队列的长度
返回值:
-
0,成功
-
-1,失败
4.accept函数
从一个监听模式的socket,等待队列中取出一个指代客户端的socket。
int accept(int sockfd, struct sockaddr* addr, socklen_t *addrlen); |
参数:
-
sockfd
:监听socket -
addr
:接收客户端地址的结构体(的地址) -
addrlen
:addr的长度(的地址)
返回值:
-
socket,成功
-
-1,失败
客户端
1.socket(略)
2.connect函数
int connect(int sockfd, struct sockaddr *secv_addr, int addrlen); |
参数:
-
sockfd
:指代服务器的socket -
secv_addr
:服务器的地址和端口(的结构体) -
addrlen
:结构体的大小
返回值:
-
0,成功
-
-1,失败
收发消息(服务器和客户端)
1.发送(send/write)
在Linux下,socket也是一个文件描述符,因此可以使用对文件操作的函数来发送消息。
1.1 send函数(默认阻塞)
ssize_t send(int sockfd, const void *buf, size_t len, int flags); |
-
sockfd
:指代客户端的socket -
buf
:指向要发送的数据缓冲区的指针。 -
len
:指定要发送的数据长度。 -
flags
:指定选项标志,填0。常见的标志有:MSG_OOB
:发送带外数据。MSG_NOSIGNAL
:在出现错误时不产生SIGPIPE信号。
返回值:
-
实际发送的数据长度,如果失败则返回-1并设置errno变量
1.2 write函数(阻塞)
头文件:<unistd.h>
ssize_t write(int fd, const void *buf, size_t count); |
参数:
-
fd
:指定要写入数据的文件描述符。 -
buf
:指向要写入的数据缓冲区的指针。 -
count
:指定要写入的数据长度。
返回值:
-
为实际写入的数据长度,如果失败则返回-1并设置errno变量
2.接收(recv/read)
2.1 recv函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags); |
参数:
-
sockfd
:指定已连接的套接字描述符,即要接收数据的来源。 -
buf
:指向接收数据缓冲区的指针。 -
len
:指定接收数据缓冲区的长度。接收的数据只会比这个少。 -
flags
:指定选项标志,填0。常见的标志有:MSG_OOB
:接收带外数据。MSG_PEEK
:接收数据但不将其从输入队列中删除。
返回值:
-
接收的数据长度
-
-1,失败
-
0,socket被关闭
2.2 read函数
ssize_t read(int fd, void *buf, size_t count); |
参数:
-
fd
:指定要读取数据的文件描述符。 -
buf
:指向接收数据缓冲区的指针。 -
count
:指定接收数据缓冲区的长度。
返回值:
-
为实际读取到的数据长度,如果失败则返回-1并设置errno变量
收尾工作
1.close函数
头文件:<unistd.h>
关闭socket。
int close(int socket); |
参数:
-
socket
:需要关闭的socket
返回值:
-
-1,失败
-
0,成功
案例
服务器
/* |
客户端
/* |