博客
关于我
linux select函数 写一个服务器,转发数据
阅读量:631 次
发布时间:2019-03-14

本文共 4713 字,大约阅读时间需要 15 分钟。

Linux select函数Server端实现数据转发

搭建一个基于Linux系统的网络服务器,实现客户端数据的接收与转发。这篇文章将详细介绍服务器端的实现步骤及工作原理。

服务器端开发概述

本节将介绍服务器端的开发流程,包括创建socket、监听客户端连接及接收并处理数据的过程。

서버端初始化

#include 
#include
#include
#include
#include
#include
#include
#include
#include

port定义与缓冲区初始化

#define PORT_SERV 8888#define BUFFSIZE 1024char receiveBuff[BUFFSIZE] = { 0 };

服务器程序开发步骤

socket创建与绑定

int main() {    int server_sockfd, client_sockfd;    int server_len, client_len;    struct sockaddr_in server_address;    struct sockaddr_in client_address;    int result;        // 创建服务器端socket    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);    server_address.sin_family = AF_INET;    server_address.sin_addr.s_addr = htonl(INADDR_ANY);    server_address.sin_port = htons(PORT_SERV);    server_len = sizeof(server_address);    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);        // 开始监听客户端连接    listen(server_sockfd, 5);        // 初始化读取集合    // FD_ZERO(&readfds);    FD_SET(server_sockfd, &readfds);        printf("server running.\n");    fflush(stdout);

客户端连接处理

while(1) {    int fd, nread;    testfds = readfds;        // 阻塞等待事件    result = select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);        if (result < 1) {        perror("server error : select() result < 1");        fflush(stdout);        exit(1);    }        // 扫描文件描述符    for(fd = 0; fd < FD_SETSIZE; fd++) {        if(FD_ISSET(fd, &testfds)) {            // 处理服务器端socket            if(fd == server_sockfd) {                client_len = sizeof(client_address);                client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, (socklen_t*)&client_len);                FD_SET(client_sockfd, &readfds);                printf("adding client on fd %d\n", client_sockfd);                fflush(stdout);                clientFDs.push_back(client_sockfd);            }            // 处理客户端socket            else {                // 获取接收缓冲区大小                ioctl(fd, FIONREAD, &nread);                                if(nread == 0) {                    close(fd);                    FD_CLR(fd, &readfds);                    printf("removing client on fd %d\n", fd);                    fflush(stdout);                    clientFDs.remove(fd);                }                else {                    read(fd, receiveBuff, nread);                    sleep(2);                    printf("client fd %d, receiveBuff :\n", fd);                    printf("%s\n", receiveBuff);                    fflush(stdout);                    clientFD_buff_map.insert(std::pair
(fd, (std::string)receiveBuff)); memset(receiveBuff, 0, BUFFSIZE); ftruncate(fd, 0); lseek(fd, 0, SEEK_SET); } // 数据转发部分 std::map
::iterator it; std::list
::iterator listIt; for(listIt = clientFDs.begin(); listIt != clientFDs.end(); listIt++) { for(it = clientFD_buff_map.begin(); it != clientFD_buff_map.end(); it++) { if(it->first != *listIt) { cout << "client " << it->first << " -> " << "data from " << listIt->first << endl; write(*listIt, it->second.c_str(), it->second.length()); } } } clientFD_buff_map.clear(); } } }}

服务器搭建说明

环境准备

推荐搭建环境:

  • 操作系统:Ubuntu 16.04 LTS
  • 网络环境:公网IP
  • 开发工具:编译器、文本编辑器(如Visual Studio Code)
  • 依赖管理:apt update && apt upgrade

实施步骤

  • 安装必要的库文件
  • sudo apt-get install build-essential model-viewer libboost-dev libboost-system-dev
    1. 编译源码
    2. g++ -o server *.[等待编译完成]

      服务启动

      ./server

      此时服务器已启动,等待客户端连接。

      QtAndroid客户端开发

      客户端需求分析

      • 网络通信:TCP协议
      • UI需求:简单的消息交互界面
      • 功能需求:文件传输、实时消息

      客户端实现步骤

    3. 生成套接字
    4. #include 
      #include
      #include
      #include
      #include
      int main() { QApplication app(FALSE); TcpSocket *socket = new TcpSocket(); socket->connectToHost(QHostInfo::localhost(), 8888); QTextBrowser browser; browser.show(); return app.exec();}

      数据接收处理

      void socketConnected() {    socket-> ㅤ timeout();    connect(socket, &TcpSocket::readyRead, this, &MainWindow::onDataReceived);}void onDataReceived() {    QString data = QString(socket->readAll());    // 显示或处理接收到的数据}

      通过上述步骤,成功实现了从服务器到客户端的数据传输功能,具备发送和接收双向通信能力,用户可以根据需求在界面上进行数据展示或处理。

      yapmış的一些补充说明

      本文在实际应用中可能会遇到一些问题,例如网络连接异常或套接字阻塞等需要注意以下几点:

    5. 防火墙设置:确保服务器端开放相应端口,避免连接被拦截
    6. 网络带宽限制:必要时可以调整套接字传输速度
    7. 客户端稳定性:优化客户端界面,提升用户体验
    8. 最后,服务器程序需要不断关注新连接申请,保持服务稳定性,同时处理客户端数据nection closure 以确保资源 finite.

    转载地址:http://fqylz.baihongyu.com/

    你可能感兴趣的文章
    为什么要使用UTF-8?
    查看>>
    Android多线程与双缓冲
    查看>>
    MVVM_Template
    查看>>
    not permitted by network security policy
    查看>>
    {spring.cloud.client.ipAddress}
    查看>>
    栈上内存溢出漏洞利用之Return Address
    查看>>
    Bugku CTF web29(Web)
    查看>>
    网络+图片加载框架(英文版)
    查看>>
    扣非净利润连续三年亏损,四维图新如何熬过“转型阵痛期”?
    查看>>
    前台报Invalid Host/Origin Header错误
    查看>>
    IE浏览器中input的placeholder不显示
    查看>>
    【CSP - S T1】格雷码
    查看>>
    Python imageio方法示例
    查看>>
    Possible missing firmware
    查看>>
    算法的学习方式
    查看>>
    JAVA BigInteger和BigDecimal类常用方式
    查看>>
    ubuntu挂载移动硬盘出现错误:mount:unknown filesystem type ‘exfat‘
    查看>>
    深度学习框架 各种模型下载集合 -- models list
    查看>>
    双层卷积神经网络--tf
    查看>>
    six.move 的作用
    查看>>