1、socket函数
//linux
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
argument 1(domain) :
AF_INET IPv4地址
AF_INET IPv6地址
argument 2(type) :
SOCK_STREAM 此协议是可靠的、按照顺序的、数据完整的基于字节流的连接。使用TCP来进行传输。
SOCK_DGRAM 此协议是不可靠的、无连接的、固定长度的传输调用。使用UDP来进行连接。
argument 3(protocol) :
传 0 表示使用默认协议。
return :
成功,返回指向新创建的socket的文件描述符。
失败,返回-1,设置errno。
2、bind函数
//linux
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
argument 1(sockfd) :
socket文件描述符
argument 2(addr) :
构造出IP地址和端口号
return :
成功返回0,失败返回-1,设置errno
服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接,因此服务器需要调用bind绑定一个固定的网络地址和端口号。
bind()的作用是将参数sockfd和addr绑定在一起,是sockfd这个用于网络通讯的文件描述符监听addr所描述的地址和端口号,前面讲过,struct sockaddr*是一个通用的指针类型,addr参数实际上可以接受多种协议的sockaddr结构体,而它们的长度各不相同,所以需要第三个参数addrlen指定结构体的长度,如:
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(6666);
首先将整个结构体清零,然后设置地址类型为AF_INET, 网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这样设置可以在所有的IP地址上监听,知道与某个客户建立了连接时才确定下来到底用哪个IP地址,端口号为6666.
3、listen函数
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd, int backlog);
argument 1(sockfd) :
socket文件描述符
argument 2(backlog) :
在linux系统中, 它是指排队等待建立3次握手队列长度
典型的服务器可以同时服务于多个客户端,当有客户端发起连接时,服务器调用accept()返回并接受这个连接,如果有大量的客户端发起连接而服务器来不及处理,尚未accept的客户端就处于连接等待状态,listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于连接等待状态,如果接收到更多的连接请求就忽略。
listen() 成功返回0,失败返回-1.
4、accpet 函数
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr* addr, socklen_t *addr_len);
argument 1(sockfd) :
socket文件描述符
argument 2(addr) :
传出参数,返回连接客户端地址信息,包括IP和端口号。
argument 3(addr) :
返回接收到地址的大小
成功返回一个新的sock文件描述符,用于连接客户端,失败返回-1
三次握手结束后,accept如果没有收到客户端连接请求,则处于阻塞状态,
5、connect 函数
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const sockaddr *addr, socklen_t addrlen);
argument 1(sockfd) :
socket文件描述符
argument 2(addr) :
传入参数,指定服务器端地址信息,包括IP地址和端口号
argument 3(addrlen) :
传入参数,传入sizeof(addr)大小
return :
成功返回0,失败返回-1
客户端调用connect连接服务器,connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对方的地址。