Socket
socket
可以算是一种特殊的文件,是"Open--Write/Read--Close"模式的一种实现,可读、可写、可控制、可关闭。普通文件的打开操作返回一个文件描述符,socket返回一个socket描述符
socket的创建
#include <sys/socket.h>
int socket(int family, int type, int protocol);
httpfd = socket(AF_INET, SOCK_STREAM, 0);
sucess return socketfd;
failed return -1; and set errno(在err流里?)
- family(domain 协议域)
AF_INET
--- IPV4(ipv6为AF_INET6
) - type(socker类型)
SOCK_STREAM
--- 面向连接的稳定数据传输 - protocol(协议)
0
选择与type一致的协议
- 其中理论上建立socket时是指定协议,应该用PF_xxxx,设置地址时应该用AF_xxxx,但是其实他们值是一致的,所以有很多混用的情况
- 建议:对于socketpair与socket的domain参数,使用PF_LOCAL系列,而在初始化套接口地址结构时,则使用AF_LOCAL。
例如:
z = socket(PF_LOCAL, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
socket的命名
创建socket只是指定了地址族,并没有具体地址.(就只有socket文件描述符,并没有绑定socket地址?).
- 将一个socket与socket地址的绑定称为命名.
- 在服务器程序中,只有命名后客户端才知道该如何连接它.(客户端就不需要命名,使用操作系统自动分配的socket地址)
#include <sys/types.h>
#include <sys/sockets.h>
int bind(int socketfd, const struct sockaddr* my_addr, socklen_t addrlen);
success return 0
failed return -1 and set errno
struct sockaddr_in
为ipv4的地址协议族


其中,port和sin_addr为网络字节序,hton(), htonl(),htons();
sock_addr
常用于bind
connect
recvfrom
sendto
等函数的参数.
#include <arpe/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr); //将点分十进制的ip地址转化为用于网络传输的数值格式
返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1
inet_pton(AF_INET, ip, &address.sin_addr)
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len); //将数值格式转化为点分十进制的ip地址格式
返回值:若成功则为指向结构的指针,若出错则为NULL
设置sockaddr的一般步骤
cosnt char* ip;
...
struct sockaddr_in address;
bzero(&address, sizeof(address)); #c
memset(&address, 0, sizeof(address)); #cpp
address.sin_family = AF_INET;
inet_pton(AF_INET, ip, &address.sin_addr);
socket监听
#include <sys/socket.h>
int listen(int sockfd, int backlog);
sucess return 0;
failed return -1 and set errno
backlog参数提示内核监听队列的最大长度,典型值为5,在linux内核版本2.2之后,表示完全连接状态的socket上限(ESTABLISHED)
到这一步已经可以建立连接了,只不过还不能进行通信
接受连接accept
#Include <sys/types.h>
#include <sys/socket.h>
int accept(int listenfd, struct sockaddr *addr, socklen_t *addrlen);
sucess return 0;
failed return -1 and set errno
如果监听队列中处理ESTABLISHED状态的client出现异常,对accept没有影响,accept只是从监听队列中取出链接.
V:我觉得accept就像是bind的另一种形式.把client客户端的信息映射到connfd上,然后存入文件描述符表中.
发起连接 connect
#Include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, cosnt struct sockaddr *serv_addr, socklen_t *addrlen);
sucess return 0;
failed return -1 and set errno
关闭连接 close
#include <unistd.h>
int close(int fd);
close系统调用并非总是立即关闭一个链接,而是将fd的引用计数减1
网友评论