1、创建socket:
int socket( int domain , int type, int protocol );
int sockfd = socket(AF_INET,SOCK_STREAM,0);
domain:即为协议域(family)。
type:指定socket类型。
常用的socket类型有:
SOCK_STREAM,
SOCK_DGRAM,
SOCK_RAW,
SOCK_PACKET,
SOCK_SEQPACKET等等。。。
procotol:顾名思义就是指定协议。
常用的协议有:
IPPROTO_TCP,
IPPTOTO_UDP,
IPPROTO_TIPC,等,他们分别对应TCP传输协议,udp传输协议,sctp传输协议。
注意:当protocol为0时,会自动选择type类型对应的默认协议。
2、bind()函数。
int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);
sockfd: 就是socket描述字,它是通过socket()函数创建了,唯一标识一个socket。bind()函数就是将给这个描述字绑定一个名字。
addr: 一个sockaddr *指针,指向要绑定给sockfd的协议地址。这个地址根据地址创建socket时的地址协议族的不同而不同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ in_port_t sin_port; /* port in network byte order */ struct in_addr sin_addr; /* internet address */ }; /* Internet address. */ struct in_addr { uint32_t s_addr; /* address in network byte order */ }; ipv6: struct sockaddr_in6 { sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* port number */ uint32_t sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */ }; struct in6_addr { unsigned char s6_addr[ 16 ]; /* IPv6 address */ }; |
addrlen:对应的就是地址的长度。
3、listen()、connect()、函数:
如果作为一个服务器,在调用socket(),bind(),之后就会调用listen()来监听这个socket,如果客户端这时调用connect()发出连接请求,服务器端就会接收到这个请求。
int listen(int sockfd,int backlog);
int connect(int sockfd, const struct sockaddr * addr, scoklen_t adrlen);
listen()第一个参数就是要监听的socket描述字,第二个参数为响应的socket可以排队的最大连接数。socket()函数创建的socket默认是一个主动类型的,listen函数将socket变成被动类型的,等待客户的连接请求。
connect()函数的第一个参数即为客户端的socket描述字,第二个参数为服务器的socket地址,第三个参数为socket地址的长度。客户端通过调用connect函数来建立与TCP服务器的连接。
accept()函数:
TCP客户端依次调用socket(),bind(),listen(),就会监听到socket地址了。TCP客户端依次调用socket()connect(),之后就想TCP服务器发送了一个连接请求。TCP服务器监听到这个情趣之后,就会调用accept()函数截取接收请求,这样连接就建立好了。之后就可以开始网络I/O操作了,即类同于普通文件的读写I/O操作。
int accept(int sockfd, struct sockaddr* addr, socklen_t addrlen);
sockfd:服务器的socket描述字,是服务器开始调用socket()函数生成的,称为监听socket套接字,而accept函数返回的是已连接的socket描述字。一个服务器通常仅仅只创建一个监听socket描述字,他在服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建了一个一连接的socket描述字,当服务器完成了对某个客户的服务,相应的已连接的socket描述字就会被关闭。