Linux 网络编程基础(3) -- 数据的IO
2014-04-09 20:24
387 查看
首先介绍两个数据结构及相关的操作函数:structiovec、structmsghdr
structiovec{
void*iov_base;/*向量的缓冲地址*/
size_tiov_len; /*向量缓冲区的大小,以字节为单位*/
};
iovec定义在linux/include/uio.h中,此数据结构与readv()和writev()联合使用。
ssize_treadv(ints,conststructiovec*vector,intcount);
返回值为成功接收的字节数。s:文件描述符vector:iovec数组的起始地址count:iovec数组的元素个数。
ssize_twritev(intfd,constiovec*vector,intcount);
返回值为成功发送的字节数。fd:文件描述符vector:发送数据的vector数组地址count:iovec数组的元素个数
应用的例子:
msghdr结构体定义在linux/include/socket.h中
structiovec{
void*iov_base;/*向量的缓冲地址*/
size_tiov_len; /*向量缓冲区的大小,以字节为单位*/
};
iovec定义在linux/include/uio.h中,此数据结构与readv()和writev()联合使用。
ssize_treadv(ints,conststructiovec*vector,intcount);
返回值为成功接收的字节数。s:文件描述符vector:iovec数组的起始地址count:iovec数组的元素个数。
ssize_twritev(intfd,constiovec*vector,intcount);
返回值为成功发送的字节数。fd:文件描述符vector:发送数据的vector数组地址count:iovec数组的元素个数
应用的例子:
/* 服务器端代码 */ #include<stdio.h> #include<stdlib.h> #include<strings.h> #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<sys/uio.h> #include<netinet/in.h> #defineServ_Port8888 #defineBackLog5 voidprocess_client_vector(intsock_cli); intmain(char*argv[],intargc) { intsock_serv,sock_cli; structsockaddr_inserver_addr; structsockaddr_inclient_addr; interr; pid_thandle_client_pid; sock_serv=socket(AF_INET,SOCK_STREAM,0); if(sock_serv<0){ printf("ErrorWhenbuildSocket\n"); return1; } bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(Serv_Port); server_addr.sin_addr.s_addr=htonl(INADDR_ANY); err=bind(sock_serv,(structsockaddr*)&server_addr,sizeof(server_addr)); if(err<0){ printf("ErrorWhenBind\n"); return1; } err=listen(sock_serv,BackLog); if(err<0){ printf("ErrorWhenListen\n"); return1; } //while(1){ intaddrlen=sizeof(structsockaddr); printf("Waiteing......\n"); sock_cli=accept(sock_serv,(structsockaddr*)&client_addr,&addrlen); if(sock_cli<0) ;//continue; handle_client_pid=fork(); if(handle_client_pid==0){ close(sock_serv); process_client_vector(sock_cli); } else close(sock_cli); //} } voidprocess_client_vector(intsock_cli) { intnumber; charstr; charch; inti=0; printf("OneclientisAccpted\n"); structiovec*recv_vector=(structiovec*)malloc(3*sizeof(structiovec)); if(!recv_vector){ printf("NOEnoughSpaceHere\n"); return; } recv_vector[0].iov_base=&number; recv_vector[0].iov_len=sizeof(number); recv_vector[1].iov_base=&str; recv_vector[1].iov_len=sizeof(str); recv_vector[2].iov_base=&ch; recv_vector[2].iov_len=sizeof(ch); ssize_tsize=readv(sock_cli,recv_vector,3); printf("RECVED:Number%dSTR:%cCHAR:%c\n",number,str,ch); }
/* 客户器端代码 */ #include<stdio.h> #include<stdlib.h> #include<strings.h> #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<sys/uio.h> #include<netinet/in.h> #defineServ_Port8888 voidprocess_server_vector(intsock_cli); intmain(char*argv[],intargc) { structsockaddr_inserver_addr; interr; intsock_cli; sock_cli=socket(AF_INET,SOCK_STREAM,0); if(sock_cli<0){ printf("ErrorWhenSocket()\n"); return1; } bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(Serv_Port); inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr); connect(sock_cli,(structsockaddr*)&server_addr,sizeof(server_addr)); process_server_vector(sock_cli); close(sock_cli); return0; } voidprocess_server_vector(intsock_cli) { intnumber=10; charstr='K'; charch='M'; ssize_tsize=0; structiovec*vector=(structiovec*)malloc(3*sizeof(structiovec)); vector[0].iov_base=&number; vector[0].iov_len=sizeof(number); vector[1].iov_base=&str; vector[1].iov_len=sizeof(str); vector[2].iov_base=&ch; vector[2].iov_len=sizeof(ch); size=writev(sock_cli,vector,3); if(size<0) printf("WritevError\n"); }
msghdr结构体定义在linux/include/socket.h中
structmsghdr{ void*msg_name;/*ptrtosocketaddressstructure*/ intmsg_namelen;/*sizeofsocketaddressstructure*/ structiovec*msg_iov;/*scatter/gatherarray*/ __kernel_size_tmsg_iovlen;/*#elementsinmsg_iov*/ void*msg_control;/*ancillarydata*/ __kernel_size_tmsg_controllen;/*ancillarydatabufferlength*/ unsignedintmsg_flags;/*flagsonreceivedmessage*/ }; 这个数据结构如果不考虑msg_falsgs,与structiovec的用法并没有很大的差别,操作这个数据结构的函数: #include<sys/uio.h> ssize_trecvmsg(ints,conststructmsghdr*msg,intflags); s:套接字msg:承接数据的消息数据结构flags:没有很大的意义, ssize_tsendmsg(ints,conststructmsghdr*msg,intflags);
s:套接字msg:承接数据的消息数据结构flags:决定以什么方式发送数据
readmsg的接收方式取决于msg结构中msg_flags的值,这也是readmsg()与函数sendmsg()的不同的地方,sendmsg()函数的发送方式有参数决定。 在没有介绍套接字的选项前,先不对msghdr的相关代码编写进行实践,因为msghdr中的msg_name,msg_control,msg_flags等成员的设定与当前使用的协议是相关的,待以后把套接字的选项介绍完后,在深入探究msghdr的使用。 除了上述介绍的几个函数,还有很多的IO函数,现总结如下:
intread(intfd,void*buffer,intnbyte); intwrite(inthandle,void*buf,intnbyte); 这两个函数可以用于任何的描述符,可以用于文件,标准输入输出,和套接字。 readv(),writev(),recvmsg(),sendmsg()的具体函数参考上面的具体内容。 intrecvfrom(ints,void*buf,intlen,unsignedintflags,structsockaddr*from,int*fromlen); s:套接字 buf:数据接收缓冲区 len:接收数据长度flags:是以下一个或者多个标志的组合体,可通过or操作连在一起 from:数据的来源的地址fromlen:地址长度。
相关文章推荐
- HTTP错误代码完全说明
- 黑马程序员_网络编程
- HTTPS协议原理
- 嵌入式开发中网络性能测试工具iperf的使用方法和注意事项
- POJ 1273 Drainage Ditches (网络流 EK && Dinic)
- TCP建立连接为什么是三次握手而不是两次握手
- XMLHttpRequest 的使用
- Ubuntu网络配置以DHCP方式配置网卡
- http://paulgraham.com/arcfaq.html
- C高级网络编程小结
- 获取 ios 系统网络状况、电量
- HttpHandler开发的两个重点问题
- web服务之https
- 关于android主线程不能访问网络异常NetworkOnMainThreadException
- 滑动窗口协议实验
- web开发下的HTTP编程及接口回调的使用
- Android 通过http调用 struts乱码问题
- HttpServletResponse
- 项目预研:Android简略、快速的网络库: Volley ( Google IO 2013 )
- iOS网络编程之Socket(客户端)