网络编程中接受连接请求的套接字创建过程可整理如下:
调用socket函数创建套接字 调用bind函数分配IP地址和端口 调用listen函数转为可接收请求状态 调用accept函数受理连接请求
函数说明
socket()函数
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
参数
domain:套接字中使用的协议族(Protocol Family)信息; type:套接字数据传输类型信息 protocol:计算机通信中使用的协议信息
协议族(Protocol Family)
头文件sys/socket.h中声明的协议族
名称 协议族 PF_INET IPv4互联网协议族 PF_INET6 IPv6互联网协议族 PF_LOCAL 本地通信的UNIX协议族 PF_PACKET 底层套接字的协议族 PF_IPX IPX Novell协议族
套接字类型(Type)
面向连接的套接字:SOCK_STREAM
传输过程中数据不会消失 按序传输数据 传输的数据不存在数据边界(Boundary)
面向消息的套接字:SOCK_DGRAM
强调快速传输而非传输顺序 传输的数据可能丢失也可能损毁 传输的数据有数据边界 限制每次传输的数据大小
协议(Protocol)
IPPROTO_TCP – TCP传输协议 IPPTOTO_UDP – UDP传输协议 IPPROTO_SCTP – STCP传输协议 IPPROTO_TIPC – TIPC传输协议
bind()函数
int bind(int sockfd, const struct sockaddr *addr, socklen_t, addrlen);
参数
sockfd:socket文件描述符 addr:一个const struct sockaddr *指针,指向要绑定给sockfd的协议地址。这个地址结构根据地址创建socket时的地址协议族的不同而不同 addrlen:对应的是地址的长度
sockaddr对应IPv4的结构体如下:
struct sockaddr_in
{
sa_family_t sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
char sin_zero[8 ];
};
struct in_addr
{
In_addr_t s_addr;
};
listen()函数
int listen(int sockfd, int backlog);
参数
sockfd:socket文件描述符 backlog:socket可以排队的最大连接个数
accept()函数
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:socket文件描述符 addr:服务器的socket地址 addrlen:socket地址的长度
connect()函数
int connect(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen);
参数
sockfd:socket文件描述符 serv_addr:服务器的socket地址 addrlen:socket地址的长度
文件操作
打开文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path, int flag);
参数
path:打开的目标文件名及路径信息 flag:文件的打开模式
文件的打开模式
打开模式 含义 O_CREAT 必要时创建文件 O_TRUNC 删除全部现有数据 O_APPEND 维持现有数据,保存到其后面 O_RDONLY 只读打开 O_WRONLY 只写打开 O_RDWR 读写打开
关闭文件
#include <unistd.h>
int close(int fd);
参数
将数据写入文件
#include <unistd.h>
ssize_t write(int fd, const void *buf, ssize_t nbytes);
参数
fd:显示数据传输对象的文件描述符 buf:保存要传输数据的缓冲地址值 nbytes:要传输数据的字节数
读取文件中的数据
#include <unistd.h>
ssize_t read(int fd, void *buf, ssize_t nbytes);
参数
fd:显示数据接收对象的文件描述符 buf:要保存接收数据的缓冲地址值 nbytes:要接收数据的最大字节数