网络编程——实现tcp和udp的双回射服务器(c++)

要实现一个兼容流式套接字(TCP)和数据包套接字(UDP)的回射服务器,我们可以使用 select 模型或事件选择模型来进行编程。

这里采用select模型

一、基本步骤:

  1. 创建套接字(socket()

  2. 绑定地址(bind()

  3. 监听连接(listen()

  4. 使用 select() 监视套接字

  5. 接受连接(accept()

  6. 读取数据(recv()

  7. 发送数据(send()

  8. 关闭套接字(close()

二、具体实现:

(1)创建tcp 和udp两个套接字

int tcp_sock, udp_sock;
struct sockaddr_in tcp_addr, udp_addr;
int addr_len = sizeof(struct sockaddr_in);
tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

(2)为了提高性能和避免“地址已被使用”的错误,我们通常需要设置一些套接字选项。

int opt = 1;
setsockopt(tcp_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(udp_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

这段代码是用来设置套接字选项的,具体是设置 SO_REUSEADDR 选项,它允许套接字立即重新绑定到一个最近被用来绑定的端口上。这在网络编程中很有用,特别是在开发阶段,因为当一个服务器程序异常退出时,绑定的端口可能会在一定时间内被操作系统保持(处于 TIME_WAIT 状态),如果没有这个选项,新的服务器进程将无法立即绑定到同一个端口。

(3)绑定地址和端口

tcp_addr.sin_family = AF_INET;
tcp_addr.sin_addr.s_addr = INADDR_ANY;
tcp_addr.sin_port = htons(TCP_PORT);

udp_addr.sin_family = AF_INET;
udp_addr.sin_addr.s_addr = INADDR_ANY;
udp_addr.sin_port = htons(UDP_PORT);

bind(tcp_sock, (struct sockaddr *)&tcp_addr, sizeof(tcp_addr));
bind(udp_sock, (struct sockaddr *)&udp_addr, sizeof(udp_addr));

(4)监听TCP

listen(tcp_sock, 5);

(5)使用 select 模型监控套接字

fd_set readfds;
FD_ZERO(&readfds);
FD_SET(tcp_sock, &readfds);
FD_SET(udp_sock, &readfds);

int max_fd = udp_sock > tcp_sock ? udp_sock : tcp_sock;

(6)循环等待处理事件

while (1) {
    fd_set fds = readfds;
    int activity = select(max_fd + 1, &fds, NULL, NULL, NULL);

    if ((activity < 0) && (errno != EINTR)) {
        error_handling("select error");
    }

    // TCP连接请求
    if (FD_ISSET(tcp_sock, &fds)) {
        int tcp_clnt_sock = accept(tcp_sock, (struct sockaddr *)&tcp_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值