Linux IO模型漫谈(3) -- 阻塞式IO实现

127 阅读4分钟
原文链接: click.aliyun.com

在理解代码前有几个函数先说一下:

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的流程基本是这样的:

clip_image001

客户端:







#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;



}





客户端的流程如下;

clip_image002






本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2012/06/04/2534178.html,如需转载请自行联系原作者