📄 example71.c
字号:
/* example71.c */
/* 阻塞式I/O */
/* 实例一 */
/*
通过下面的简单的例子详细说明阻塞套接字及其缺陷。
server端创建服务,接受client端的请求,并为每一个请求派生出一个服务进程。(一直在循环等待接受client端的请求)
client端发送请求,当与server端建立连接以后,就向server端发送一个字符串。在client端创建了两个连接,然后server对第一个请求先睡眠3秒后再给客户端返回信息。而对第二个连接则立即返回信息。所以在第一个连接睡眠过程中,第二个连接已经有数据可读了,但由于对第一个soket的读操作处于阻塞状态,所以第二个soket上虽有数据可读但也无法获得数据,只有对第一个socket读操作成功返回后,才能读第二个soket上的操作。这正是阻塞I/O的缺点。
*/
/* 服务器端程序 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#define MAXLEN 1024
#define SERV_PORT 8080
#define BACKLOG 5
void serv();
int main()
{
int listenfd, connetfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0) ) < 0) {
perror("socket error");
exit(0);
}
bzero( &servaddr, sizeof(servaddr) );
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if ( (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr) ) ) < 0) {
perror("bind error");
exit(0);
}
if (listen(listenfd, BACKLOG) < 0) {
perror("listen error");
exit(0);
}
for ( ; ; ) { // 每有一个连接请求就建立一个连接
clilen = sizeof(cliaddr);
connetfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
if ( (childpid = fork() ) == 0) { // 每个连接开个进程
close(listenfd);
serv(connetfd);
exit(0);
}
close(connetfd);
}
}
void serv(int connfd)
{
ssize_t n;
char line[MAXLEN];
for ( ; ; ) {
if ((n = read(connfd, line, MAXLEN)) == 0) {
perror("connect closed by client");
exit(0);
}
if (line[0] == '1') {
sleep(3);
write(connfd, "server respons to client1", 26);
}
else
write(connfd, "server respons to client2", 26);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -