select的socket server多路复用模型

本文介绍了如何使用select系统调用来实现一个TCP Socket服务器的多路复用模型,通过示例代码展示了如何监听并处理多个客户端连接。相较于多进程,作者更倾向于使用多线程,因为多线程具有更低的代价且能共享数据。
摘要由CSDN通过智能技术生成

除了上文将的通过fork多进程socket server模型外, 另一种方法是使用select系统调用。当然,也可以对上文的fork进行修改,例如使用pthread创建线程来完成具体工作。

两种方法各有优缺点,都不是最优解决方案。但没种解决方案都不是绝对的,我们可以混合使用各种解决方案来完成,关键是能够理解socket,select,多线程,多进程的本质。相对于多进程fork的方式,我更喜欢使用pthread多线程,原因之一是pthread的代价更低,更重要的原因是多线程可以共享数据,省去了多进程之间通信的代价。

多进程socket server例程:http://www.9say.com/2009/01/multi-process-socket-server-demo-example/

以下是使用select多路复用的socket server模型的一个例子:

/**

 *        @brief:        server.c

 *

 *        A simplest tcp connection example of server side.

 * use select to accept multi-client connections.

 *

 *        guotie.9(at)gmail.com

 *

 */

#include <stdio.h>

#include <string.h>

#include <signal.h>

 

#include <sys/select.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <errno.h>

#include <unistd.h>

 

#define TRANSFER_PORT               6688

#define MAX_LISTEN       12

 

int init_transfer();

void fini_transfer();

 

int recv_data(int sock, char *buf, int len);

 

int sig_handler(void);

void sig_handler_func(int sig);

int select_conns();

 

int transfer_sock;

 

int init_transfer()

{

        int sock = -1;

        struct sockaddr_in addr;

 

        printf(”init transfer ……/n”);

        sock =  socket(PF_INET, SOCK_STREAM, 0);

        if(-1 == sock)

        {

perror(”Failed to create socket./n”);

return -1;

        }

        memset(&addr, 0, sizeof(struct sockaddr_in));

 

        addr.sin_family =       AF_INET;

        addr.sin_addr.s_addr = inet_addr(”0.0.0.0″);

        addr.sin_port = htons(TRANSFER_PORT);

 

        if(-1 == bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)))

        {

perror(”Failed to bind socket./n”);

return -1;

        }

 

        if(-1 == listen(sock, MAX_LISTEN))

        {

printf(”Failed to bind socket. errno: %d/n”, errno);

return -1;

        }

 

        transfer_sock = sock;

 

        printf(”      %s: init transfer socket %d …… success/n”, __FUNCTION__, sock);

 

        return 0;

}

 

void fini_transfer()

{

        int ret;

 

        ret = shutdown(transfer_sock, SHUT_RDWR);

 

        ret = close(transfer_sock);

        if(ret < 0)

             perror(”/nfini_transfer: “);

        else

             printf(”/n/n      %s: success shutdown transfer socket!/n/n”, __FUNCTION__);

}

 

int recv_data(int sock, char *buf, int len)

{

        int l = 0;

 

        memset(buf, 0, len);

        l = recv(sock, buf, len, 0);

        if(0 > l)

        {

          

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值