socket in C
一些常用的函数:
int socket(int domain, int type, int protocol);
domain可选值:
PF_UNIX,PF_LOCAL: 本地通信AF_INET,PF_INET: IPv4 InternetPF_INET6: IPv6 InternetPF_IPX: IPX-NovellPF_NETLINK: 内核用户界面设备
type可选值:
SOCK_STREAM: 流式套接字, TCPSOCK_DGRAM: 数据包套接字, UDPSOCK_SEQPACKET: 序列化包SOCK_RAW: RAW类型, 提供原始网络协议访问SOCK_RDM: 提供可靠的数据报文, 不过可能数据有乱序SOCK_PACKET: 专用类型, 不能再通用程序中使用
protocol可选值:
- 通常协议中只有一种特定类型, 这时protocol参数只能设置为0
返回值:
sockfd: 一个套接字描述符- -1: 发生了错误, 全局变量
errno被设置为错误代码
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
sockfd: 一个socket()函数返回的套接字描述符
my_addr: 一个sockaddr指针, 包含地址信息(名称, 端口, IP地址)
addrlen: 可以设置为sizeof(struct sockaddr)
返回值: -1表示发生错误, errno为错误代码
int listen(int sockfd, int backlog);
sockfd: 一个socket()返回的套接字描述符
backlog: 未经处理的连接请求队列的最大容量
返回值: -1表示发生了错误, errno为错误代码
int accept(int sockfd, void *addr, int *addrlen);
sockfd: 一个socket()返回的套接字描述符
addr: 一个struct sockaddr_in指针, 存储着远程连接过来的计算机信息(IP, 端口)
addrlen: 值应该是sizeof(struct sockaddr), accept()不会在addr中存储多于addrlen的字节, 如果addr中的数据不够addrlen, accept()会改变addrlen的值
调用情景:
- 有人从其他地方尝试用
connect()连接你的某个端口(已经在listen()) listen()将连接请求加入accept()的等待队列- 调用
accept()连接一个连接请求 accept()返回一个新的套接字描述符, 表示建立的连接
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
sockfd: socket()返回的套接字描述符
serv_addr: 存储着远程计算机的信息(IP, 端口)
addrlen: 应该是sizeof(struct sockaddr), 实际上是socklen_t类型
int recv(int sockfd, void *buf, int len, int flags);
sockfd: 要读取数据的套接字描述符
buf: 字符缓冲区指针, 用来放接收到的数据
len: 缓冲区长度
flags: recv()的一个标志, 一般为0
返回值: 实际接收到的数据长度, -1表示发生了错误, errno为错误代码
int send(int sockfd, const void *msg, int len, int flags);
sockfd: 远程连接的套接字描述符
msg: 字节数据指针
len: 数据长度
flags: 发送标记, 一般为0
返回值: 实际发送的数据长度, -1表示发生了错误, errno为错误代码
send()有可能发送不完全部数据, 也就是说, 如果返回值小于len就需要再次发送剩下的数据
key_t ftok(const char *path, int id);
path: 路径, 只要存在就行
id: 虽然是int, 但是只有8位, 随意设置
返回值: key_t的值, -1表示发生了错误
ftok通过路径提取文件信息, 再根据这些信息和id合成key_t
int msgget(key_t key, int msgflg);
key:
- 0(
IPC_PRIVATE)表示建立新的消息队列 - 大于0, 根据
msgflg来确定操作, 一般来源于ftok()返回的IPC键值
msgflg:
- 0表示取消消息队列标识符, 如果不存在则报错
IPC_CREAT: 当msgflg & IPC_CREAT为真时, 如果不存在键值与key相等的消息队列, 就新建一个, 如果存在这样的消息队列, 返回其标识符IPC_CREAT | IPC_EXCL: 如果不存在键值与key相等的消息队列就新建一个, 如果存在就报错
返回值: 一个用key命名的消息队列的标识符, -1表示发生错误
int msgsnd(int msqid, const void *msg, size_t msgsz, int msgflg);
msqid: msgget()返回的消息队列标识符, 表示目标消息队列
msg: 要发送的消息
msgsz: 消息的长度
msgflg:
- 0表示当目标消息队列已满的时候, 阻塞当前消息的发送, 直到消息能进入目标消息队列
IPC_NOWAIT: 当消息队列已满的时候, 不等待, 立即返回IPC_NOERROR: 若要发送的消息过大, 则将消息截断并把多余部分丢弃, 且不通知发送进程
返回值: 0表示成功, -1表示发生了错误