tcp并发服务器通讯模型有哪些

tcp并发服务器通讯模型有哪些,第1张

服务器创建并绑定套接字后fork出几个子进程,子进程中分别进行accept(该函数为阻塞函数)、recv、处理数据然后再次acept,这样循环下去。所有客户端发来的信息都是直接由子进程处理。

例程

代码如下,在处理客户端请求之前,服务器先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继续监听。

/


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/325973.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存