sockets: 套接字的IO函数

###########################################################

套接字的IO函數

IO函数都涉及到阻塞问题,所以要考虑超时问题.

推荐使用sendmsg和recvmsg函数。

对socket的操作:

#include<sys/types.h>

#include <sys/socket.h>

ssize_t recv(int sockfd, void*buff, size_t len, int flags);

ssize_t send(int sockfd, constvoid *buff, size_t len, int flags);

ssize_t recvfrom(int sockfd,void *buff, size_t len, int flags, struct sockaddr *servaddr, socklen_t*addrlen);

ssize_t sendto(int sockfd,const void *buff, size_t len, int flags, const struct sockaddr *servaddr,socklen_t addrlen);

ssize_t recvmsg(int sockfd,struct msghdr *msg, int flags);

ssize_t sendmsg(int sockfd,const struct msghdr *msg, int flags);

flags:

MSG_DONTROUTE:发送绕过路由表查找

MSG_DONTWAIT:接收操作非阻塞

MSG_OOB:发送或接收带外数据

MSG_WAITALL:接收等待所有数据

MSG_PEEK:接收窥看外来消息

struct msghdr

{

void *msg_name; // 未连接对端套接字地址

socklen_t msg_namelen; //对端地址长度

struct iovec *msg_iov; // 缓冲区的地址信息

size_t msg_iovlen; // 缓冲区个数

 void *msg_control; //指向辅助数据

   size_t msg_controllen; //辅助数据长度

int msg_flags; // recvmsg返回的标志

};

辅助数据的组成:cmsghdr + 填充字节 + 数据

struct cmsghdr

{

socklen_t cmsg_len;// 填充字节+数据+cmsghdr的长度

int cmsg_level;//原始协议IPPROTO_XXX

int cmsg_type;//协议专用类型SCM_XXX

__extension__ unsigned char _cmsg_data __flexarr;//数据

};

可用的宏:

#include <sys/socket.h>

#include <sys/param.h>

struct cmsghdr *CMSG_FIRSTHDR(structmsghdr *mhdrptr);

返回第一个cmsghdr结构的指针;

struct cmsghdr *CMSG_NXTHDR(structmsghdr *mhdrptr, struct cmsghdr *cmsgptr);

返回下一个cmsghdr结构的指针;

unsigned char *CMSG_DATA(structcmsghdr *cmsgptr);

返回第一个cmsghdr结构的数据的指针;

unsigned int CMSG_LEN(unsignedint legth);

unsigned int CMSG_SPACE(unsignedint length);

对复合缓冲区的操作:

#include <sys/uio.h>

ssize_t readv(int fd, conststruct iovec *iov, int iovcnt);

将fd中的数据读到散布的缓冲区iov中。

ssize_t writev(int fd, conststruct iovec *iov, int iovcnt);

从散布的缓冲区iov中将数据聚集写到fd中。

ssize_t preadv(int fd, conststruct iovec *iov, int iovcnt, off_t offset);

ssize_t pwritev(int fd, conststruct iovec *iov, int iovcnt, off_t offset);

struct iovec

{

void *iov_base;   //buffer address

size_t iov_len;   //buffer length

};

iovcnt表示结构数组iov中的结构个数,不能超过IOV_MAX。

对文件描述符的操作:

#include <unistd.h>

ssize_t read(int fd, void*buff, size_t count);

ssize_t write(int fd, constvoid *buf, size_t count);

###########################################################

IO复用(使用select函数或poll函数):

在网络编程时有标准IO和套接字IO等多个IO时,进程需要一种预先告知内核的能力,使得内核进程指定的一个或多个IO条件就绪就通知进程,这就是IO复用。

一个输入操作通常需要两个阶段:

1.    等待数据准备好

2.    从内核向进程复制数据

等待的三种条件:

一 怎样判断一个套接字准备好读:

3.     套接字接受缓冲区的数据字节数大于等于套接字接收缓冲区低水位标记的当前值。SO_RCVLOWAT设置这个值,unix默认为1,linux默认为18

2.该连接的读半部关闭(对端发送一个FIN)

3.该套接字是一个监听套接字,且已完成的连接数不为0

4.该套接字有一个套接字错误待处理。

二 怎样判断一个套接字准备好写:

1.     套接字发送缓冲区中的可用空间字节数大于等于套接字发送缓冲区低水位值,

SO_SNDLOWAT设置这个值,unix默认值为2048,linux默认为19.

2.该连接的写半部关闭

3.使用非阻塞的connect套接字已建立连接,或connect已经以失败告终。

4.该套接字有一个套接字错误待处理。

三 异常条件:

1.带外数据

时间: 2024-10-29 19:07:01

sockets: 套接字的IO函数的相关文章

11 非阻塞套接字与IO多路复用(进阶)

1.非阻塞套接字 第一部分 基本IO模型 1.普通套接字实现的服务端的缺陷 一次只能服务一个客户端! 2.普通套接字实现的服务端的瓶颈!!! accept阻塞! 在没有新的套接字来之前,不能处理已经建立连接的套接字的请求. recv 阻塞! 在没有接受到客户端请求数据之前, 不能与其他客户端建立连接! 3.普通服务器的IO模型 第二部分 非阻塞套接字 1.非阻塞套接字与普通套接字的区别 >>> import socket >>> server = socket.sock

非阻塞套接字与IO多路复用

我们了解了socket之后已经知道,普通套接字实现的服务端的缺陷:一次只能服务一个客户端! 并且,为了使一个客户端能够不断收发消息,我们还要使用while循环来轮询,这极大地降低了我们的效率 accept阻塞! 在没有新的套接字来之前,不能处理已经建立连接的套接字的请求 recv 阻塞! 在没有接受到客户端请求数据之前,不能与其他客户端建立连接 可以用非阻塞接口来尝试解决这个问题! 阻塞IO模型 阻塞IO(blocking IO)的特点:就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被

TCP套接字编程常用函数

socket函数 这是一个进程在执行网络I/O之前必须调用的函数,用于指定期望的通信协议类型 #include <sys/socket.h> int socket(int family, int type, int protocol); // 调用成功返回非负的套接字描述符,出错返回-1 connect函数 TCP客户端用connect函数来建立与TCP服务器的连接 #include <sys/socket.h> int connect(int sockfd, const stru

套接字I/O函数write/read writev/readv send/recv sendto/recvfrom sendmsg/recvmsg

函数原型 read/write系原型 1 #include <unistd.h> 2 3 ssize_t read(int fd, void *buf, size_t count); 1 #include <unistd.h> 2 3 ssize_t write(int fd, const void *buf, size_t count); 1 #include <sys/uio.h> 2 3 ssize_t readv(int fd, const struct iov

sockets: 套接字选项相关的系统调用

########################################################### 套接字选项相关的系统调用: ########################################################### 将optval指向的单元中的值设置给optname选项: int setsockopt(int sockfd, int level, int optname, const void *optval,socklen_t optlen)

ZeroMQ接口函数之 :zmq_socket – 创建ZMQ套接字

ZeroMQ API 目录 :http://www.cnblogs.com/fengbohello/p/4230135.html 翻译:风波 mail : [email protected] ————————————————————————————————————— ZeroMQ 官方地址:http://api.zeromq.org/4-0:zmq-socket zmq_socket(3)            ØMQ Manual - ØMQ/4.0 Name zmq_socket – 创建Z

【UNIX网络编程(二)】基本TCP套接字编程函数

基于TCP客户/服务器程序的套接字函数图如下: 执行网络I/O,一个进程必须做的第一件事就是调用socket函数,指定期望的通信协议类型. #include <sys/socket.h> int socket(int family, int type, int protocol);/*返回值:若成功则为非负描述符,若出错则为-1*/ socket函数成功时返回一个小的非负整数值,它与文件描述符类似,把它称为套接字描述符,简称sockfd.family参数指明协议族,被称为协议域.type参数指

Unix网络编程随手记——套接字接口函数

套接字接口(socket interface)是一组函数,它们和Unix I/O函数结合起来,用以创建网络应用.大多数现代系统上都实现套接字接口,包括所有的Unix变种.Windows和Macintosh. 1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: 1 struct sockaddr 2 { 3 unsigned short sa_family; /* address族, AF_xxx */ 4 char sa_data[14]; /* 14

套接字编程(VC_Win32)

简介(源于维基) Berkeley套接字(也作BSD套接字应用程序接口)刚开始是4.2BSD Unix操作系统(于1983发布)的一套应用程序接口.然而,由于AT&T的专利保护着UNIX,所以只有在1989年Berkeley大学才能自由地发布自己的操作系统和网络库.Berkeley套接字接口,一个应用程序接口(API),使用一个Internet套接字的概念,使主机间或者一台计算机上的进程间可以通讯. 它可以在很多不同的输入/输出设备和驱动之上运行,尽管这有赖于操作系统的具体实现. 接口实现用于T