您的位置:首页 > 理论基础 > 计算机网络

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

2015-12-14 10:02 796 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: