大体上,连接的建立过程就是:服务器在确定协议类型后,向外广播IP地址和端口号,并监听等待,直到客户端获取了IP地址和端口号并成功连接:
使用socket来进行tcp协议的网络编程的大体步骤:
其实socket的使用就像之前文件编程中打开文件的操作一样,返回的是一个标识符,之后就对这个标识符进行操作。
参考:linux网络编程:网络socket基础编程(一) 基础API_Jags的博客-CSDN博客
创建套接字的函数
#include
#include
int socket(int domain, int type, int protocol);
AF_INET:IPv4因特网域 (最常用,TCP/IP的协议族)
AF_INET6:IPv6因特网域
AF_UNIX:Unix域
AF_ROUTE:路由套接字
AF_KEY:密钥套接字
AF_UNSPEC:未指定
... ...
SOCK_STREAM:字节流套接字(提供可靠,面向连接的信息流,使用TCP协议,保证了数据的正确性和顺序性)
SOCK_DGRAM:数据报套接字(提供无连接的服务,数据可以通过相互独立的报文进行传输,是无序的,并且不能保证可靠性,使用UDP协议)
SOCK_RAW:原始套接字(运行程序使用底层协议如IP或ICMP直接进行访问,功能强大但使用不便,主要用于协议的开发)
... ...
IPPROTO_TCP:tcp协议
IPPROTO_UDP:udp协议
IPPROTO_SCTP:sctp协议
IPPROTO_TIPC:tipc协议
... ...
服务器绑定IP和端口号到网络标识符的函数
#include
#include
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//ipv4(AF_INET)对应的地址结构 struct sockaddr{ unsigned short as_family; //协议族 char sa_data[14]; //IP+端口号 }; 等价于,下面这种是优化版 struct sockaddr_in{ sa_family_t sin_family; //协议族 in_port_t sin_port; //端口号 struct in_addr sin_addr; //IP地址结构体 unsigned char sin_zero[8]; //填充,没有实际意义,只是为了跟socketaddr结构在内存中对齐,这样两者才能相互转换 };
服务器监听设置的函数
#include
#include
int listen(int sockfd, int backlog);
服务器接受连接的函数,用于从已完成连接队列的队头返回下一个已完成连接,如果已完成连接队列为空,那么进程投入睡眠
#include
#include
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
客户端连接的函数,如果是TCP套接字,调用 connect函数将激发TCP的三路握手过程
#include
#include
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
地址转换的API
#include
#include
#include
int inet_aton(const char *cp, struct in_addr *inp);
//把字符串形式的“192.168.X.XXX”转为网络能识别的格式
char *inet_ntoa(struct in_addr in);
//把网络格式的IP地址转为字符串形式
在套接字通讯中进行字节读取函数
和之前文件的的读写函数名字一样,但参数不太一样,因为在套接字的通讯中,输入或输出的字节可能比请求的少。
使用详见:使用read write 读写socket_san.hang的博客-CSDN博客
#include
ssize_t write(int fd, const void *buf, size_t nbytes);
//将buf中的nbytes个字节写入到文件描述符fd,成功时返回写的字节数
ssize_t read(int fd, void *buf, size_t nbyte);
//从fd读取nbyte个字节到buf中,返回实际所读的字节数
网络I/O还有一些函数,例如 recv()/send(); readv()/writev(); recvmsg()/sendmsg()等...
另一组用于socket数据收发的API
#include
#include
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);