Linux IO模型漫谈(3) -- 阻塞式IO实现
2012-06-04 09:48 轩脉刃 阅读(2246) 评论(0) 编辑 收藏 举报在理解代码前有几个函数先说一下:
1 sockaddr_in 套接字地址结构
struct sockaddr_in { uint8_t sin_len; //长度字段,这个sockaddr_in结构的长度,一般不用设置和检查它 sa_family_t sin_family; //协议族,TCP,UDP等协议族就设置为AF_INET in_port_t sin_port; //端口号 struct in_addr sin_addr; //32位的IPv4地址 char sin_zero(8); //未使用 }
POSIX规范只需要指定其中的sin_family, sin_port, sin_addr三个字段
这个结构非常重要!!
2 socket函数(创建套接字)
#include <sys/socket.h> int socket(int family, int type, int protocol)
参数解释:
family:协议族,和sockaddr_in中的sin_family一个意思
type: 指明套接字类型
Protocol:通常赋值为0
这个函数是所有套接字编程的入口,创建套接字。
3 htons函数
这个函数是将本地字节序列转换为网络字节序列,简单来说,就是将一个数的高低位互换
(如12 34 -> 3412)
这个函数在给servaddr_in赋值的时候会用到
下面这个程序包含了基本的IO操作,说明以注释的形式加在代码中;
服务器端:
#include <stdio.h> //这个头包含了最简单的输入和输出 #include <sys/types.h> //这个头包含了系统调用的大量数据结构 #include <sys/socket.h> //这个头包含了socket的结构 #include <netinet/in.h> //这个头包含了internet地址解析的一些数据结构 #include <string.h> #include <unistd.h> int main(int argc, char *argv[]) { int listenfd, portno; //文件描述符 int clifd, clilen; struct sockaddr_in serv_addr,cli_addr; //socketadd_in定义在netinet/in.h中 listenfd = socket(AF_INET, SOCK_STREAM, 0); //创建一个套接字 bzero((char *) &serv_addr, sizeof(serv_addr)); //初始化 serv_addr.sin_family = AF_INET; //设置协议族 serv_addr.sin_port = htons(7777); //设置端口 serv_addr.sin_addr.s_addr = INADDR_ANY; //设置socket的另一端的地址信息,由于这里是server程序,因此设置为ANY bind(listenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); //绑定地址,将本地协议地址赋予一个套接字 listen(listenfd, 5); //监听socket,第二个参数规定了内核应该为相应套接字排队的最大连接数个数,不要设置为0 clilen = sizeof(cli_addr); clifd = accept(listenfd, (struct sockaddr *) &cli_addr, &clilen); //当有客户端连接的时候,进入连接队列 char buffer[256]; bzero(buffer, 256); read(clifd, buffer, 255); //读取客户端发送的消息 printf("The Message is:%s\r\n", buffer); write(clifd, "I get the message", 17); //往客户端发送消息 close(clifd); close(listenfd); return 0; }
server的流程基本是这样的:
客户端:
#include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <string.h> #include <unistd.h> int main(int argc, char* argv[]) { int socketfd; socketfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serv_addr; bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(7777); connect(socketfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)); write(socketfd, "client message", 14); char buffer[256]; bzero(buffer, 256); read(socketfd, buffer, 255); printf("server return message:%s\r\n", buffer); return 0; }
客户端的流程如下;
实时了解作者更多技术文章,技术心得,请关注微信公众号“轩脉刃的刀光剑影”
本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系。