例程
代码如下,在处理客户端请求之前,服务器先fork了3个子进程,然后将客户端的请求直接交由子进程处理。
该例程中,服务器fork子进程后,子进程监听并接收客户端的信息,然后打印客户端发来的信息和自己的id(id代表自己是第几个子进程)
服务器端代码:
/**************************************
author:arvik
purpose:test the server simultaneity
email:1216601195@qq.com
csdn: http://blog.csdn.net/u012819339
**************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define BUFFLEN 1024
#define SERVER_PORT 8887
#define BACKLOG 5
#define PIDNUMB 3
static void handle_connect(int s_s, int id)
{
int s_c
struct sockaddr_in from //client addr
socklen_t len = sizeof(from)
while(1)
{
s_c = accept(s_s, (struct sockaddr*)&from, &len)
char buff[BUFFLEN]
memset(buff, 0, BUFFLEN)
int n = recv(s_c, buff, BUFFLEN, 0) //non block
if(n >0)
{
printf("This process id is: %d \nreveive from client: %s\n", id, buff)
}
close(s_c)
}
}
void sig_int(int num)
{
exit(1)
}
int main(int argc, char **argv)
{
int s_s
struct sockaddr_in local
signal(SIGINT, sig_int)
s_s = socket(AF_INET, SOCK_STREAM, 0)
memset(&local, 0, sizeof(local))
local.sin_family = AF_INET
local.sin_addr.s_addr = htonl(INADDR_ANY)
local.sin_port = htons(SERVER_PORT)
bind(s_s, (struct sockaddr*)&local, sizeof(local))
listen(s_s, BACKLOG)
pid_t pid[PIDNUMB]
for(int i = 0i<PIDNUMBi++)
{
pid[i] = fork()
if(pid[i] == 0)
{
handle_connect(s_s, i)
}
}
sleep(100)
close(s_s)
return 0
}
客户端代码:
/**************************************
author:arvik
purpose:test the server simultaneity
email:1216601195@qq.com
csdn: http://blog.csdn.net/u012819339
**************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <signal.h>
#define BUFFLEN 24
#define SERVER_PORT 8887
int main()
{
int s_c
struct sockaddr_in server
char buff[] = "hello"
s_c = socket(AF_INET, SOCK_STREAM, 0)
memset(&server, 0, sizeof(server))
server.sin_family = AF_INET
server.sin_addr.s_addr = htonl(INADDR_ANY)//any local address
server.sin_port = htons(SERVER_PORT)
connect(s_c, (struct sockaddr*)&server, sizeof(server))
send(s_c, buff, strlen(buff), 0)
sleep(1)
close(s_c)
return 0
}
大家都知道各类网络服务器程序的编写步骤,并且都知道网络服务器就两大类:循环服务和并发服务。这里附上源代码来个小结吧。一、 循环服务
循环网络服务器编程实现的步骤是这样的:
建立socket(这里用到socket()函数及函数setsockopt())
|
|
\|/
把socket和IP地址及端口绑定(这里用到bind函数)
|
|
\|/
开始监听(这里用到listen()函数)
|
|
/\
/\
\ / \
----------------------- | 有连接|
| / \ /
| \ /
| \ /
| |
| 接受新的连接(这里用到accept()函数)
| | /___________________________________________________
| | \|
| \|/ |
| 从连接里读取数据(这里用到recv()系统函数,当然也可以是read()函数) |
|||
| ||
| \|/ |
| 返回信息给连接(这里用到send()系统函数,当然也可以是write()函数)|
| ||
| ||
| /\ |
| /\ |
| / \ |
| | 还有数据 |-Y-------------------------------------------------------
| \ /
| \ /
| \ /
|_______________________________|
这种服务器模型是典型循环服务,如果不加上多进程/线程技术,此种服务吞吐量有限,大家都可以看到,如果前一个连接服务数据没有收发完毕后面的连接没办法处理。所以一般有多进程技术,对一个新连接启用一个新进程去处理,而监听socket继续监听。
/
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)