Linux 网络编程基础(3) -- 数据的IO
首先介绍两个数据结构及相关的操作函数:struct iovec、struct msghdr
struct iovec {
void * iov_base; /*向量的缓冲地址*/
size_t iov_len; /*向量缓冲区的大小,以字节为单位*/
};
iovec定义在linux/include/uio.h中,此数据结构与readv()和writev()联合使用。
ssize_t readv(int s, const struct iovec *vector, int count);
返回值为成功接收的字节数。 s: 文件描述符 vector:iovec数组的起始地址 count:iovec数组的元素个数。
ssize_t writev(int fd, const iovec *vector, int count);
返回值为成功发送的字节数。 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>
#define Serv_Port 8888
#define BackLog 5
void process_client_vector(int sock_cli); int main(char *argv[], int argc)
{
int sock_serv, sock_cli;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr; int err;
pid_t handle_client_pid; sock_serv = socket(AF_INET, SOCK_STREAM, );
if(sock_serv < ){
printf("Error When build Socket\n");
return ;
} 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, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(err < ){
printf("Error When Bind\n");
return ;
} err = listen(sock_serv, BackLog);
if(err < ){
printf("Error When Listen\n");
return ;
} // while(1){
int addrlen = sizeof(struct sockaddr);
printf("Waiteing... ...\n");
sock_cli = accept(sock_serv, (struct sockaddr*)&client_addr, &addrlen); if(sock_cli < )
;//continue;
handle_client_pid = fork();
if(handle_client_pid == ){
close(sock_serv);
process_client_vector(sock_cli);
}
else
close(sock_cli);
// }
} void process_client_vector(int sock_cli)
{
int number;
char str;
char ch;
int i = ;
printf("One client is Accpted\n");
struct iovec *recv_vector = (struct iovec*)malloc(*sizeof(struct iovec)); if(!recv_vector){
printf("NO Enough Space Here\n");
return;
} recv_vector[].iov_base = &number;
recv_vector[].iov_len = sizeof(number); recv_vector[].iov_base = &str;
recv_vector[].iov_len = sizeof(str); recv_vector[].iov_base = &ch;
recv_vector[].iov_len = sizeof(ch); ssize_t size = readv(sock_cli, recv_vector, );
printf("RECVED: Number%d STR: %c CHAR:%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> #define Serv_Port 8888
void process_server_vector(int sock_cli); int main(char *argv[], int argc)
{
struct sockaddr_in server_addr;
int err;
int sock_cli; sock_cli = socket(AF_INET, SOCK_STREAM, );
if(sock_cli < ){
printf("Error When Socket()\n");
return ;
} 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, (struct sockaddr *)&server_addr, sizeof(server_addr)); process_server_vector(sock_cli); close(sock_cli); return ;
} void process_server_vector(int sock_cli)
{
int number = ;
char str = 'K';
char ch = 'M';
ssize_t size = ; struct iovec *vector = (struct iovec *)malloc(*sizeof(struct iovec)); vector[].iov_base = &number;
vector[].iov_len = sizeof(number); vector[].iov_base = &str;
vector[].iov_len = sizeof(str); vector[].iov_base = &ch;
vector[].iov_len = sizeof(ch); size = writev(sock_cli, vector, );
if(size < )
printf("Writev Error\n");
}
msghdr 结构体定义在linux/include/socket.h中
struct msghdr {
void *msg_name; /* ptr to socket address structure */
int msg_namelen; /* size of socket address structure */
struct iovec *msg_iov; /* scatter/gather array */
__kernel_size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data */
__kernel_size_t msg_controllen; /* ancillary data buffer length */
unsigned int msg_flags; /* flags on received message */
};
这个数据结构如果不考虑msg_falsgs,与struct iovec的用法并没有很大的差别,操作这个数据结构的函数:
#include<sys/uio.h>
ssize_t recvmsg(int s, const struct msghdr *msg, int flags);
s: 套接字 msg:承接数据的消息数据结构 flags:没有很大的意义,
ssize_t sendmsg(int s, const struct msghdr *msg, int flags );
s: 套接字 msg:承接数据的消息数据结构 flags:决定以什么方式发送数据
readmsg的接收方式取决于msg结构中msg_flags的值,这也是readmsg()与函数sendmsg()的不同的地方,sendmsg()函数的发送方式有参数决定。 在没有介绍套接字的选项前,先不对msghdr的相关代码编写进行实践,因为msghdr中的msg_name,msg_control,msg_flags 等成员的设定与当前使用的协议是相关的,待以后把套接字的选项介绍完后,在深入探究msghdr的使用。 除了上述介绍的几个函数,还有很多的IO函数,现总结如下:
int read(int fd, void * buffer, int nbyte);
int write(int handle, void *buf, int nbyte);
这两个函数可以用于任何的描述符,可以用于文件,标准输入输出,和套接字。 readv(), writev(),recvmsg(),sendmsg()的具体函数参考上面的具体内容。 int recvfrom(int s,void *buf,int len,unsigned int flags ,struct sockaddr *from ,int *fromlen);
s: 套接字 buf:数据接收缓冲区 len:接收数据长度 flags:是以下一个或者多个标志的组合体,可通过or操作连在一起
from:数据的来源的地址 fromlen: 地址长度。
Linux 网络编程基础(3) -- 数据的IO的更多相关文章
- 服务器编程入门(4)Linux网络编程基础API
问题聚焦: 这节介绍的不仅是网络编程的几个API 更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系. 这节主要介绍三个方面的内容:套接字( ...
- Linux 高性能服务器编程——Linux网络编程基础API
问题聚焦: 这节介绍的不仅是网络编程的几个API 更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系. 这节主要介绍三个方面的内容:套接字(so ...
- 第5章 Linux网络编程基础
第5章 Linux网络编程基础 5.1 socket地址与API 一.理解字节序 主机字节序一般为小端字节序.网络字节序一般为大端字节序.当格式化的数据在两台使用了不同字节序的主机之间直接传递时,接收 ...
- Linux网络编程基础API
第5章 Linux网络编程基础API 探讨Linux网络编程基础API与内核中TCP/IP协议族之间的关系,并未后续章节提供编程基础.从3个方面讨论Linux网络API. socket地址API.so ...
- linux高性能服务器编程 (五) --Linux网络编程基础api
第五章 Linux网络编程基础api 1.主机字节序和网络字节序 字节序是指整数在内存中保存的顺序.字节序分为大端字节序.小端字节序. 大端字节序:一个整数的高位字节数据存放在内存的低地址处.低位字节 ...
- linux 网络编程 基础
网络编程基础 套接字编程需要指定套接字地址作为参数,不同的协议族有不同的地址结构,比如以太网其结构为sockaddr_in. 通用套接字: struct sockaddr { sa_family_t ...
- linux网络编程基础--(转自网络)
转自 http://www.cnblogs.com/MyLove-Summer/p/5215287.html Linux下的网络编程指的是socket套接字编程,入门比较简单. 1. socket套接 ...
- Linux网络编程基础
1. Linux网络模型 ① OSI七层模型和Linux四层模型 ② 各种协议之间的关系及在Linux模型中的位置 ③ 协议封装:各种协议处于一种层层封装的关系 (1)Ethernet (2)IP * ...
- 5 Linux网络编程基础API
5.1 socket地址API 大端字节序(网络序):高位在低址,低位在高址 小端字节序(主机序):低位在低址,高位在高址 判断,利用联合的特性: #include <iostream> ...
随机推荐
- vsftpd限制用户不能更改根目录
在IE下登陆会出现如下图所示情况,当时直接吓尿了,尼玛这台危险了.仔细一想可定是在配置vsftpd.conf时没有设置用户不能更改根目录:
- 关于 css padding 的使用 padding会将使用该属性的元素撑开
.right_img_box{ width:300px; height:250px; border:1px solid #c9c9c9; margin-bottom:15px; background: ...
- Flink Program Guide (1) -- 基本API概念(Basic API Concepts -- For Java)
false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...
- 内存(MRC)
一.计数器的基本操作1> retain : +1, 方法返回的是对象本身2> release :-13> retainCount : 获得计数器4> dealloc * 当一 ...
- Android中pendingIntent的深入理解
pendingIntent字面意义:等待的,未决定的Intent.要得到一个pendingIntent对象,使用方法类的静态方法 getActivity(Context, int, Intent, i ...
- vagrant打造自己的开发环境
vagrant打造自己的开发环境 缘由: 在网上看到斌哥,爽神都写了关于vagrant的博客,都在说很强大,所以很好奇这玩意怎么个强大,然后也就自己来一发玩玩看看. 真实缘由: 说实话是电脑配置太低, ...
- uva 10003 Cutting Sticks (区间dp)
本文出自 http://blog.csdn.net/shuangde800 题目链接: 打开 题目大意 一根长为l的木棍,上面有n个"切点",每个点的位置为c[i] 要按照一 ...
- CodeForces 135C C. Zero-One
题目 题意: 一个01串,AB两个人轮流删去一个字符,直到只剩两个,A先手.最后剩的两位组成一个二进制数,A要使其最小,B要使其最大. 有一些部分不知道原来是什么,用?表示,求所有的可能里,最后剩下的 ...
- 执行startx后Ubuntupassword正确进不去的问题
今天在命令行里敲了 startx ,然后系统重新启动.输入password后,跳转到一下界面.之后又返回到登陆界面.一直这样循环输入password.进不去系统. 然后不得不用手机在网上查找解决的方法 ...
- 初探swift语言的学习笔记(闭包 - 匿名函数或block块代码)
很多高级语言都支持匿名函数操作,在OC中的block也为大家所熟悉,然面在swift里好像是被重新作了一个定义,不叫匿名函数,或 block了,而叫闭包(closure).下面配合代码来理解一下swi ...
