博客
关于我
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/

    你可能感兴趣的文章
    idea在连接mysql数据库时区错误
    查看>>
    springboot中访问static下的图片没反应
    查看>>
    PHP文件域上传文件
    查看>>
    2021-05-14
    查看>>
    PHP入门笔记--include和require
    查看>>
    Java IO整理总结之字符流
    查看>>
    SpringMVC接收数据时String转Date的问题
    查看>>
    Spring Boot在idea上热部署
    查看>>
    Kali-linux:nmap命令
    查看>>
    php端口直驱网络打印机,能自定义格式
    查看>>
    我的OpenGL学习摘要_变换_矩阵
    查看>>
    更新Ubuntu上的python版本
    查看>>
    【资源共享】DEVFreq 开发指南
    查看>>
    NXP IMX7ULP 开发板编译和烧录固件
    查看>>
    部署vue +koa+nginx前后端分离项目到服务器
    查看>>
    整合mybatis方式一:mybatis-spring
    查看>>
    多线程并发问题
    查看>>
    java8 函数式编程
    查看>>
    Spark ML算法简单了解 Kmeans
    查看>>
    s5p6818内核修改和重新编译
    查看>>