参考网址: peitianyu/TcpIpBook: TCP/IP网络编程 (github.com)
TCP/IP网络通信之Socket编程入门_哔哩哔哩_bilibili
套接字操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include<sys/socket.h> # 创建套接字 int socket(int domain, int type, int protocol); //成功时返回文件描述符,失败时返回-1 # 分配地址信息 int bind(int sockfd, struct sockaddr* pSockAddr, socklen_t addrLen); //成功时返回0, 失败时返回-1 # 设置监听 int listen(int sockfd, int backlog); //成功时返回0, 失败时返回-1 # 受理连接 int accept(int sockfd, struct sockaddr* pSockAddr, socklen_t* pAddrLen); //成功时返回文件描述符,失败时返回-1 # 请求连接 int connect(in sockfd, struct sockaddr* pSockAddr, socklen_t sockLen); //成功时返回0, 失败时返回-1
文件操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 # 打开文件 #include<fcntl.h> int open(const char* path, int flag); //成功时返回文件描述符, 失败时返回-1 # 关闭文件 #include<unistd.h> int close(int fd); //成功时返回0, 失败时返回-1 # 写入文件 #include<unistd.h> ssize_t write(int sockfd, const void* buf, size_t nBytes); //成功时返回写入的字节数,失败时返回-1 # 读取文件 ssize_t read(int sockfd, void* buf, size_t nBytes); //成功时返回读到的字节数(若遇到文件结尾则返回0),失败时返回-1 #include<sys/uio.h> # 写文件 ssize_t writev(int sockfd, const struct iovec* iov, int iovcnt); //成功时返回发送的字节数,失败时返回-1 # 读文件 ssize_t readv(int sockfd, const struct iovec* iov, int iovcnt); //成功时返回发送的字节数,失败时返回-1 // TCP // 发送文件 ssize_t send(int sockfd, const void* buf, size_t nbytes, int flags); //成功时返回发送的字节数,失败时返回-1 // 接收文件 ssize_t recv(int sockfd, const void* buf, size_t nbytes, int flags); //成功时返回接收到的字节数(收到EOF时返回0),失败时返回-1 // UDP接收发送 ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t *addrlen); //成功时返回发送的字节数,失败时返回-1,参数flags 一般设0 ssize_t recvfrom(int sockfd, const void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t *addrlen); //成功时返回接收的字节数,失败时返回-1,参数flags 一般设0 struct iovec { void* iov_base; //缓冲地址 size_t iov_len; //缓冲大小 } # 断开连接 int shutdown(int sock, int howto); //成功时返回0,失败时返回-1
套接字的可选项和IO缓冲大小 1 2 3 4 5 #include<sys/socket.h> int getsockopt(int sock, int level, int optname,void* optval,socklen_t* optlen); //成功时返回0,失败时返回-1 int setsockopt(int sock, int level, int optname, void* optval,socklen_t optlen); //成功时返回0,失败时返回-1
1 2 3 4 5 6 7 8 int sock = socket(PF_INET,SOCK_STREAM,0); int optval; socklen_t optlen; int state = getsockopt(sock, SOL_SOCKET, SO_SNDBUF,(void*)&optval, &optlen); optval = 1024*3; optlen = sizeof(optval); state = setsockopt(sock, SOL_SOCKET, SO_RCVBUF,(void*)&optval,optlen);
IO复用
FD_ZERO(fd_set* fdset)
: 将fdset变量的所有位初始化位0
FD_SET(int fd, fd_set* fdset)
: 向fdset变量中注册文件描述符fd
FD_CLR(int fd, fd_set* fdset)
: 清除fdset变量中的文件描述符fd
FD_ISSET(int fd, fd_set* fdset)
: fdset变量中是否存在fd文件描述符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 设置监视范围及超时 #include<sys/select.h> #include<sys/time.h> int select(int maxfd, fd_set* readset, fd_set* writeset,fd_set* exceptset, const struct timeval* timeout ); //失败时返回-1,超时返回0,成功时返回发生事件的文件描述符数量 struct timeval { long tv_sec; long tv_usec; }
maxfd: 监视的文件描述符数量(最大的文件描述符+1)
readset: 将关注“是否存在待读取数据”的文件描述符存放在readset变量中
writeset: 将关注”是否可写“的文件描述符存放在writeset变量中
exceptset: 将关注”是否有异常“的文件描述符放在exceptset变量中 -timeout: 为了防止调用select函数后陷入无限阻塞状态,可以传递超时信息