网络编程--IO模型示例(阻塞式IO)

IO模型在Richard Stevens的《UNIX网络编程,第一卷》(程序猿必备!)一书中有非常详尽的描述,以下简要介绍,并给出代码示例。

另外比较好的总结性blog,推荐:
使用异步 I/O 大大提高应用程序的性能
IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)

常见网络IO模型:阻塞式IO、无阻塞式IO、IO复用、异步IO、信号驱动

阻塞式IO:

在一个进程发出IO请求后,进入阻塞状态,直到内核返回数据,才重新运行,如图:


代码
sever端:

/***************************************************************************
 * 
 * Copyright (c) 2015 ****.com, Inc. All Rights Reserved
 * 
 **************************************************************************/
 
 
 
/**
 * @file server.c
 * @author yangjingyuan01
 * @date 2015/12/13 19:54:19
 * @brief 
 *  
 **/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>



int main(){
    
    int sock_fd, client_fd;
    int sin_size, numbytes;
    struct sockaddr_in server_addr, client_addr;
    
    //create socket
    if((sock_fd = socket(AF_INET,SOCK_STREAM,0)) < 0){
        perror("Socket create failed");
        return -1;
    }


    //init socket
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5001);
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);

    //bind socket
    if(bind(sock_fd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))==-1){
        perror("bind failed");
        return -1;
    }
    
    //listen socket
    if(listen(sock_fd,10) == -1){
        perror("listen failed");
        return -1;
    }

    printf("Server is running\n");

    char buff[1024];
    while(1){
        sin_size = sizeof(struct sockaddr_in);
        //accept connection
        if((client_fd = accept(sock_fd,(struct sockaddr*)&client_addr,(socklen_t*)&sin_size)) == -1){
            perror("accept failed");
            return -1;
        }

        if(!fork()){       
            //child processes
            memset(buff,0,sizeof(buff));
            if((numbytes = recv(client_fd,buff,sizeof(buff),0)) == -1){
                perror("recv error");
                return -1;
             }
    
            printf("buff=%s\n");


            if(send(client_fd,buff,strlen(buff),0) == -1){
                perror("send");
            }
        
            close(client_fd);
            return 0;
        }
        //parent process close child file descriptor
        close(client_fd);
    }

    close(sock_fd);
    return 0;
}


/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */

client 端:

/***************************************************************************
 * 
 * Copyright (c) 2015 ***.com, Inc. All Rights Reserved
 * 
 **************************************************************************/
 
 
 
/**
 * @file client.c
 * @author yangjingyuan01(com@***.com)
 * @date 2015/12/13 20:53:04
 * @brief 
 *  
 **/

#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>



int main(int argc,char *argv[]){

    if(argc != 3){
        printf("%s input IP & port \n",argv[0]);
        return 1;
    }

    int sock_fd,numbytes;
    char buf[100] = "hello world";
    struct hostent *he;
    struct sockaddr_in their_addr;


    //transform ip address
    he = gethostbyname(argv[1]);


    //create socket
    if((sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1){
        perror("socket failed");
        exit(1);
    }

    
    //init struct
    their_addr.sin_family = AF_INET;
    their_addr.sin_port = htons(atoi(argv[2]));
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    bzero(&(their_addr.sin_zero),8);


    //make connection
    if(connect(sock_fd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1){
        perror("connect failed");
        exit(1);
    }
    
    sleep(5);

    //send message to server
    if(send(sock_fd,buf,strlen(buf),0) == -1){
        perror("send failed");
        exit(1);
    }
    
    sleep(5);

    //accept info from server
    if((numbytes = recv(sock_fd,buf,100,0)) == -1){
        perror("recv failed");
        exit(1);
    }
    printf("recv: %s\n",buf);
    
    close(sock_fd);
    return 0;
}


/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */

编译:

gcc server.c -o server

gcc client.c -o client


运行:

./server

./client localhost 5001


结果:

-----Server-----

Server is running

buff=hello world

----Client-----

recv: hello world


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值