精华内容
下载资源
问答
  • 在《linux多线程服务端编程》的8.5节讲述了基于eventloop,channel,acceptor等底层的类构建TCP server的过程,以及TcpConnection的初步实现...首先还是看应用程序(使用tcpserver类的程序): #include "TcpServer.h" #

    在《linux多线程服务端编程》的8.5节讲述了基于eventloop,channel,acceptor等底层的类构建TCP server的过程,以及TcpConnection的初步实现。这块的程序被各式各样的回调函数所充斥着,可读性不是太好。现在把相关程序的流程记录一下,方便以后的学习。

    首先还是看应用程序(使用tcpserver类的程序):

    #include "TcpServer.h"
    #include "EventLoop.h"
    #include "InetAddress.h"
    #include <stdio.h>
    
    void onConnection(const muduo::TcpConnectionPtr& conn)
    {
      if (conn->connected())
      {
        printf("onConnection(): new connection [%s] from %s\n",
               conn->name().c_str(),
               conn->peerAddress().toHostPort().c_str());
      }
      else
      {
        printf("onConnection(): connection [%s] is down\n",
               conn->name().c_str());
      }
    }
    
    void onMessage(const muduo::TcpConnectionPtr& conn,
                   muduo::Buffer* buf,
                   muduo::Timestamp receiveTime)
    {
      printf("onMessage(): received %zd bytes from connection [%s] at %s\n",
             buf->readableBytes(),
             conn->name().c_str(),
             receiveTime.toFormattedString().c_str());
    
      printf("onMessage(): [%s]\n", buf->retrieveAsString().c_str());
    }
    
    int main()
    {
      printf("main(): pid = %d\n", getpid());
    
      muduo::InetAddress listenAddr(9981);
      muduo::EventLoop loop;
    
      muduo::TcpServer server(&loop, listenAddr);
      server.setConnectionCallback(onConnection);
      server.setMessageCallback(onMessage);
      server.start();
    
      loop.loop();
    }

    上述程序是使用Tcpserver类构建了一个简易的 tcp 服务器,然后写了两个简单的回调函数onConnection, onMessage。当新接收一个Tcp 连接时候,server会调用onconnection,而每次收到数据时server则会调用onmessage来完成业务逻辑。下面具体来分析tcp server处理请求的流程。

    首先是构建一个server对象

    muduo::TcpServer server(&loop, listenAddr);
    loop 和 listenAddr被用于构造server对象,tcpserver的构造函数如下:

    TcpServer::TcpServer(EventLoop* loop, const InetAddress& listenAddr)
      : loop_(CHECK_NOTNULL(loop)),
        name_(listenAddr.toHostPort()),
        acceptor_(new Acceptor(loop, listenAddr)),
        started_(false),
        nextConnId_(1)
    {
      acceptor_->setNewConnectionCallback(
          boost::bind(&TcpServer::newConnection, this, _1, _2));
    }
    

    如上所示,构造函数中会创建一个acceptor_对象来负责TCP请求的连接,Acceptor类自身的构造函数中会完成相应的socket准备工作,并且设定用于接收请求的channel回调函数Acceptor::handleRead。

    在Acceptor::handleRead的实现中,首先是调用accept()系统调用来接收连接,然后就会调用acceptor_->setNewConnectionCallback()方法,从而对应到tcpserver::newconnection中。


    接下来是传递两个自定义回调函数onConnection,onMessage的句柄:

      server.setConnectionCallback(onConnection);
      server.setMessageCallback(onMessage);
    这两个自定义的回调函数会在Tcpserver::newconnection中被使用,这个方法的源码:

    void TcpServer::newConnection(int sockfd, const InetAddress& peerAddr)
    {
      loop_->assertInLoopThread();
      char buf[32];
      snprintf(buf, sizeof buf, "#%d", nextConnId_);
      ++nextConnId_;
      std::string connName = name_ + buf;
    
      LOG_INFO << "TcpServer::newConnection [" << name_
               << "] - new connection [" << connName
               << "] from " << peerAddr.toHostPort();
      InetAddress localAddr(sockets::getLocalAddr(sockfd));
      // FIXME poll with zero timeout to double confirm the new connection
      TcpConnectionPtr conn(
          new TcpConnection(loop_, connName, sockfd, localAddr, peerAddr));
      connections_[connName] = conn;
      conn->setConnectionCallback(connectionCallback_);
      conn->setMessageCallback(messageCallback_);
      conn->setCloseCallback(
          boost::bind(&TcpServer::removeConnection, this, _1));
      conn->connectEstablished();
    }
    
    在这个方法中会新创建一个TcpConnection对象,这个对象以后就负责管理这个刚刚创建好的tcp连接,而onConnection,onMessage这两个回调函数的句柄会被赋值给TcpConnection对象。最后在这个方法中会调用connectEstablished方法:

    void TcpConnection::connectEstablished()
    {
      loop_->assertInLoopThread();
      assert(state_ == kConnecting);
      setState(kConnected);
      channel_->enableReading();
      connectionCallback_(shared_from_this());
    }
    
    这个函数里面会调用channel_->enableReading(),从而将channel加入loop中,然后调用用户自定义的connectionCallback_。当然,这里的channel是在tcp_connection中新创建的chanel对象,并为其设置了新的回调函数方法,如下:

    cpConnection::TcpConnection(EventLoop* loop,
                                 const std::string& nameArg,
                                 int sockfd,
                                 const InetAddress& localAddr,
                                 const InetAddress& peerAddr)
      : loop_(CHECK_NOTNULL(loop)),
        name_(nameArg),
        state_(kConnecting),
        socket_(new Socket(sockfd)),
        channel_(new Channel(loop, sockfd)),
        localAddr_(localAddr),
        peerAddr_(peerAddr)
    {
      LOG_DEBUG << "TcpConnection::ctor[" <<  name_ << "] at " << this
                << " fd=" << sockfd;
      channel_->setReadCallback(
          boost::bind(&TcpConnection::handleRead, this, _1));
      channel_->setWriteCallback(
          boost::bind(&TcpConnection::handleWrite, this));
      channel_->setCloseCallback(
          boost::bind(&TcpConnection::handleClose, this));
      channel_->setErrorCallback(
          boost::bind(&TcpConnection::handleError, this));
    }
    接下来,loop会继续循环,此时TCP连接已经建立好了。下一步poll返回时,实际上就是要进行数据交互了,而完成数据交互的回调函数则是由TcpConnection定义的各种handle方法来实现。比如说tcpConnection::handleRead

    void TcpConnection::handleRead(Timestamp receiveTime)
    {
      int savedErrno = 0;
      ssize_t n = inputBuffer_.readFd(channel_->fd(), &savedErrno);
      if (n > 0) {
        messageCallback_(shared_from_this(), &inputBuffer_, receiveTime);
      } else if (n == 0) {
        handleClose();
      } else {
        errno = savedErrno;
        LOG_SYSERR << "TcpConnection::handleRead";
        handleError();
      }
    }
    

    这个回调函数会先调用read系统调用读取数据到bufer,当读取的数据非量非0时,下一步就会调用messageCallback_这个用户自定义的函数来完成业务逻辑了,

    以上就是整个程序的执行流程,对client而言,只需要定义并注册几个回调函数。底层的机制会完成相应的socket处理,并且在相应的时候比如连接建立时,有数据到来时调用用户自定义的函数来完成业务逻辑。

    展开全文
  • 它采用非阻塞 IO 模型,基于事件驱动和回调,原生支持多核多线程,适合编写 Linux 服务端多线程网络应用程序。 muduo网络的核心代码只有数千行,在网络编程技术学习的进阶阶段,muduo是一个非常值得学习的开源。...

    Muduo网络库简介

    muduo 是一个基于 Reactor 模式的现代 C++ 网络库,作者陈硕。它采用非阻塞 IO 模型,基于事件驱动和回调,原生支持多核多线程,适合编写 Linux 服务端多线程网络应用程序。
    muduo网络库的核心代码只有数千行,在网络编程技术学习的进阶阶段,muduo是一个非常值得学习的开源库。目前我也是刚刚开始学习这个网络库的源码,希望将这个学习过程记录下来。这个网络库的源码已经发布在GitHub上,可以点击这里阅读。目前Github上这份源码已经被作者用c++11重写,我学习的版本是没有使用c++11版本的。不过二者大同小异,核心思想是没有变化的。点这里可以看我的源代码。从笔记十七开始记录muduo的net库的实现过程。如果你需要看一下基础库(base)的复现过程,可以点击这里:muduo的base库实现过程。而网络库的笔记在这里:
    muduo网络库源码复现笔记(十七):什么都不做的EventLoop
    muduo网络库源码复现笔记(十八):Reactor的关键结构
    muduo网络库源码复现笔记(十九):TimeQueue定时器
    muduo网络库源码复现笔记(二十):EventLoop::runInloop()函数和EventLoopThread类
    muduo网络库源码复现笔记(二十一):Acceptor类、InetAddress类、Sockets类、SocketsOps.cc

    1 TcpServer类

    前面我们讲了Acceptor类,我们也说过这个类用于监听网络连接。实际上用户将不会直接使用这个类,这个类实际上是由TcpServer类来调用的。
    TcpServer类的作用是管理由Acceptor获得的网络连接,并建立相应的TcpConnection连接。下面看一下它的代码:

    class TcpServer : boost::noncopyable
    {
    public:
    	//typedef boost::function<void(EventLoop*)> ThreadInitCallback;
    	//TcpServer(EventLoop* loop,const InetAddress& listenAddr);
    	TcpServer(EventLoop* loop,const InetAddress& lostenAddr,
    			  const string& nameArg);
    	
    	~TcpServer();
    
    	const string& hostport() const {return hostport_;}
    	const string& name() const {return name_;}
     
    	//start the server
    	void start();
    
    	void setConnectionCallback(const ConnectionCallback& cb)
    	{	connectionCallback_ = cb;	}
    
    	void setMessageCallback(const MessageCallback& cb)
    	{	messageCallback_ = cb;	}
    
    private:
    	void newConnection(int sockfd,const InetAddress& peerAddr);
    	
    	typedef std::map<string,TcpConnectionPtr> ConnectionMap;
    	EventLoop* loop_;
    	const string hostport_;
    	const string name_;
    	boost::scoped_ptr<Acceptor> acceptor_;
    	ConnectionCallback connectionCallback_;
    	MessageCallback messageCallback_;
    	bool started_;
    	// in loop thread
    	int nextConnId_;
    	ConnectionMap connections_;
    };
    

    TcpServer通过ConnectionMap掌管连接,map的key是连接名称,value是TcpConnection类的指针。
    其中最值得注意的是newConnection函数,这个函数将在TcpServer被创立的时候绑定给acceptor_,若acceptor监听到新的网络连接,newConnection将会被调用。newConnection会创建一个TcpConnection,将其指针加入map,设置相应的connectionCallback和messageCallback。代码如下:

    void TcpServer::newConnection(int sockfd,const InetAddress& peerAddr)
    {
    	loop_ -> assertInLoopThread();
    	char buf[32];
    	snprintf(buf,sizeof buf,":%s#%d",hostport_.c_str(),nextConnId_);
    	++nextConnId_;
    	string connName = name_ + buf;
    
    	LOG_INFO << "TcpServerLLnewConnection [" << name_
    			 << "] - new connection [" << connName
    			 << "] from " << peerAddr.toIpPort();
    
    	InetAddress localAddr(sockets::getLocalAddr(sockfd));
    	
    	TcpConnectionPtr conn(new TcpConnection(loop_,
    											connName,
    											sockfd,
    											localAddr,
    											peerAddr));
    	connections_[connName] = conn;
    	conn -> setConnectionCallback(connectionCallback_);
    	conn -> setMessageCallback(messageCallback_);
    
    	conn -> connectEstablished();
    }
    

    2 TcpConnection类初步

    TcpConnection类是muduo最复杂、最核心的类。它的作用如前所述,便是进行一次Tcp连接。这一节的TcpConnection还比较简陋,先初步看看它的成员。

    private:
    	enum stateE {/*kDisConnected*/kConnecting,kConnected/*,kDisConnecting*/};
    	void handleRead(Timestamp receiveTime);
    	void setState(stateE s) { state_ = s; }	
    	
    	EventLoop* loop_;
    	string name_; //connection name
    	stateE state_;
    	boost::scoped_ptr<Socket> socket_;
    	boost::scoped_ptr<Channel> channel_;
    	InetAddress localAddr_;
    	InetAddress peerAddr_;
    	ConnectionCallback connectionCallback_;
    	MessageCallback messageCallback_;
    

    TcpConnection有两个成员很重要,分别是socket_和channel_。socket_是一个Socket类指针,指向的Socket的socket的文件描述符便是与客户端通信的connfd。channel_的作用是,当建立连接时,将connfd与channel_绑定,然后将channel_加入到poller中,方便后续的通信。
    connectionCallback_与messageCallback_实际上会由TcpServer设置,分别在建立连接和通信时调用。

    展开全文
  • spprocpool是Unix / Linux预分支的服务器。 包括几个TCP预分支服务器框架。 包括一个通用的非服务器进程池,它可以在多线程环境中使用。
  • server.c #include <stdio.h> #include <event2/event.h> #include <event2/bufferevent.h> #include <event2/listener.h> #include <arpa/inet.h> #include <string.h> #...

    server.c

    #include <stdio.h>
    #include <event2/event.h>
    #include <event2/bufferevent.h>
    #include <event2/listener.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #define PORT 9999
    #define IP "127.0.0.1"
    void read_cb(struct bufferevent *bev, void *arg)
    {
    	char buf[1024];
    	memset(buf, '\0', sizeof(buf));
    	//从缓冲区读取数据
    	bufferevent_read(bev, buf, sizeof(buf));
    	printf("client send data: %s\n", buf);
    	char *p = "i am server, i got you.\n";
    	//注意数据向缓冲区写完,才会回调write_cb
    	bufferevent_write(bev, p, strlen(p));
    }
    void write_cb(struct bufferevent *bev, void *arg)
    {
    	printf("i am server, write data.... done!\n");
    }
    void event_cb(struct bufferevent *bev, short events, void *arg)
    {
    	if(events & BEV_EVENT_EOF)
    	{
    		printf("connection closed\n");
    	}
    	else if(events & BEV_EVENT_ERROR)
    	{
    		printf("error\n");
    	}
    	bufferevent_free(bev);
    }
    void listen_cb(struct evconnlistener *listener, evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr)
    {
    	char ip[16];
    	memset(&ip, '\0', sizeof(ip));
    	struct sockaddr_in *client_addr = (struct sockaddr_in*)&addr;
    	printf("receive connection from ip:%s port:%d\n", inet_ntop(AF_INET, &client_addr->sin_addr.s_addr, ip, sizeof(ip)), ntohs(client_addr->sin_port));
    
    	struct event_base *base = (struct event_base*) ptr;
    	struct bufferevent *bev = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE);
    
    	bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL);
    	//启用bufferevent读缓冲,(默认创建时,读缓冲处于关闭状态,写缓冲处于开启状态)
    	bufferevent_enable(bev, EV_READ);
    }
    int main()
    {
    	struct event_base *base = event_base_new();
    	
    	//初始化地址结构
    	struct sockaddr_in serv_addr;
    	memset(&serv_addr, 0, sizeof(serv_addr));
    	serv_addr.sin_family = AF_INET;
    	serv_addr.sin_port = htons(PORT);
    	//创建监听服务器
    	struct evconnlistener *evl = evconnlistener_new_bind(base,
    			listen_cb,
    			base,
    			LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
    			-1,
    			(struct sockaddr*)&serv_addr,
    			sizeof(serv_addr));
    	//释放资源
    	event_base_dispatch(base);
    	evconnlistener_free(evl);
    	event_base_free(base);
    	return 0;
    }
    
    

    client.c

    #include <stdio.h>
    #include <event2/event.h>
    #include <event2/bufferevent.h>
    #include <event2/listener.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #define PORT 9999
    #define IP "127.0.0.1"
    void read_cb(struct bufferevent *bev, void *arg)
    {
    	char buf[1024] = {0};
    	//memset(buf, '\0', sizeof(buf));
    	bufferevent_read(bev, buf, sizeof(buf));
    	printf("server send data: %s\n", buf);	
    }
    void write_cb(struct bufferevent *bev, void *arg)
    {
    	printf("i am client,write data.... done!\n");
    }
    void event_cb(struct bufferevent *bev, short events, void *arg)
    {
    	if(events & BEV_EVENT_EOF)
    	{
    		printf("connection closed\n");
    	}
    	else if(events & BEV_EVENT_ERROR)
    	{
    		printf("error\n");
    	}
    	else if(events & BEV_EVENT_CONNECTED)
    	{
    		printf("已经连接服务器\n");
    		return;
    	}
    	printf("free bufferevent...\n");
    	bufferevent_free(bev);
    }
    
    
    void read_terminal_cb(evutil_socket_t fd, short what, void *arg)
    {
    	char buf[BUFSIZ] = {0};
    	int len = read(fd, buf, sizeof(buf));
    	struct bufferevent *bev = (struct bufferevent*) arg;
    	bufferevent_write(bev, buf, len);
    }
    int main()
    {
    	int fd = socket(AF_INET, SOCK_STREAM, 0);
    	struct event_base *base = event_base_new();
    	struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    	
    	struct sockaddr_in serv_addr;
    	memset(&serv_addr, 0, sizeof(serv_addr));
    	serv_addr.sin_family = AF_INET;
    	serv_addr.sin_port = htons(PORT);
    	inet_pton(AF_INET, IP, &serv_addr.sin_addr.s_addr);
    	
    	int ret = bufferevent_socket_connect(bev, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    	
    	bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL);
    //	bufferevent_setcb(bev, read_cb, write_cb, NULL, NULL);
    	//启用bufferevent读缓冲,(默认创建时,读缓冲处于关闭状态,写缓冲处于开启状态)
    	bufferevent_enable(bev, EV_READ);
    
    	if(ret < 0)
    	{
    		perror("bufferevent_socket_connect error");
    		return -1;
    	}
    	//设置并监听终端输入事件
    	struct event *ev = event_new(base,
    			STDIN_FILENO,
    			EV_READ | EV_PERSIST,
    			read_terminal_cb, bev);
    	//添加事件
    	event_add(ev, NULL);
    
    	event_base_dispatch(base);
    	//释放资源
    	event_free(ev);
    	bufferevent_free(bev);
    	event_base_free(base);
    	return 0;
    }
    
    
    
    展开全文
  • server端#include using namespace std; #include #include //套接信息需要的头文件 #include #include #include #include //用信号回收进程 #include //标准头文件 #include //waitpid需要的头文件...

    server端

     

    client端

     

    服务端:

    1、socket

    2、bind

    3、listen

    4、accpet

    5、收发

    客户端:

    1、socket

    2、connect

    3、收发

    展开全文
  • 有真心想学习的,需要的朋友,底下留言哦! server.c: #include &lt;sys/types.h&gt; #include &lt;sys/stat.h&gt; #include &lt;sys/file.h&gt; #include &lt;stdio.h&gt; ...
  • 我本来开开心心的写了一个select的server和client,在ubuntu上跑的开开心心的。然后就就把程序移植到mips的君正T21的开发板上,后来发现重复调用server(退出再进入),后发现bind ...我有2个可疑点1)可能是tcp端...
  • 安装svn服务器 // 查看是否安装svn rpm -qa | grep subversion // 安装svn yum install subversion.x86_64 -y ...firewall-cmd --zone=public --add-port=3690/tcp --permanent 创建一个svn仓库 [svn@caox...
  • Sdk.Create_HP_TcpServer(pListener); if (pServer == IntPtr.Zero) { Console.WriteLine("Create_HP_TcpServer Failed"); return; } Console.WriteLine($"Server start state before ...
  • TCP/IP使用openssl ssl 例子

    千次阅读 2013-11-22 12:34:48
    server.c /************关于本文档********************************************  * *filename: ssl-server.c  * *purpose: 演示利用OpenSSL 进行基于IP ... * Linux 爱好者Linux 知识传播者SOHO 族开发者
  • /*Server.c*/ #include &amp;lt;stdio.h&amp;gt; // 标准输入输出 perror函数 #include &amp;lt;string.h&amp;gt; // 字符数组相关函数 bzero函数 strcmp #include &amp;lt;stdlib.h&amp;gt...
  • linux找不到动态的解决办法

    千次阅读 2017-03-20 23:42:22
    问题描述今天在运行jsonrpc-cpp的examples(./tcp-server)时,报错 error while loading shared libraries: libjson.so: cannot open shared object file: No such file or directory 但是查看/usr/local/lib是...
  • Linux多线程服务端编程:使用muduo C++网络》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。...
  • 原书名:Internetworking With TCP/IP Vol Ⅲ:Client-Server Programming And Applications Linux/POSIX Sockets V 作者: (美)DOUGLAS E.COMER DAVID L.STEVENS 译者: 赵刚 林瑶 蒋慧 等 丛书名: 国外计算机...
  • 另v4l2_rtsp_server和alsa_rtsp_server需要依赖别的,默认不编译,稍后介绍 运行h264_rtsp_server 进入example目录 # cd example/ 运行h264_rtsp_server # ./h264_rtsp_server test.h264 运行后会出现一行提示,...
  • RK3399更换过3个不同的开发板,也使用过不同的client程序(一个是基于muduo写的应用程序,一个是基于linux的socket接口写的测试程序) 详细问题描述在这儿(因为提问的地方没法发图片,只好这样了): ...
  • 调试Modbus TCP, 在codeblocks中打开源码tests文件夹中的random-test-server.c, 编译时出错如下: undefined reference to 'modbus_new_tcp' ... modbus不是Linux默认的,连接时需要使用静态...
  • linux下 端口复用的问题

    千次阅读 2012-02-06 14:43:20
    not allow reuse of same local port for both TCP server and TCP client.而且小测试程序能够成功,和我的测试程序的差别也就在这一点了,因此接受连接和发起连接的端口分开即可。 其他资料: 这个是捣乱...
  • Linux NFS文件共享服务

    2018-11-03 11:30:54
    NFS(网络文件系统)服务可以将远程linux系统上的文件共享资源挂载到本地的主机目录上,从而使得本地主机(linux客户端)基于TCP/IP协议,像使用本地主机上的资源读写远程linux系统上的共享文件。 RHEL7系统...
  • 如果不走TCP 传输, TCP区间端口可以不开放 如果不走UDP 传输, UDP区间端口可以不开放 TCP 区间大小 = 最大并发数(包括直播和回放) ,可以手动修改端口区间 UDP 区间大小 = 最大并发数(包括直播和回放)*2 ,可以手动...
  • 官方githubhttps://github.com/chriskohlhoff/asio​github.com我看的例子是这个目录下的/asio/src/examples/cpp11/echo/async_tcp_echo_server.cpp如果你想在linux下编译asio,需要在cmake加如下代码set(CMAKE_...
  • 官方githubhttps://github.com/chriskohlhoff/asio​github.com我看的例子是这个目录下的/asio/src/examples/cpp11/echo/async_tcp_echo_server.cpp如果你想在linux下编译asio,需要在cmake加如下代码set(CMAKE_...
  • 2. Server 端的动态名为 RC32s.dll/RC64s.dll,负责接收Client端的请求并应答返回。 Client 端由三大类组成:Connection类、Command类和Fields类 1. Connection类主要负责与Server端的通讯和应答返回值的分发; 2...
  • socket linux2

    2016-01-10 19:08:00
    //协议族使用tcp/ip server_sockaddr.sin_port=htons(PORT);//设置端口号 server_sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);//设置ip地址为本机地址 server_len=sizeof(server_sockaddr);//服务端结构体的...
  • muduo网络学习:基本架构及流程分析基本架构Basic ReactorMutiple Reactor + ThreadPoolmuduo的基本使用基本结构介绍EventLoop类Poller类Channel类TcpConnection类Acceptor类TcpServer类流程梳理 之前一直在...
  • Linux does not allow reuse of same local port for both TCP server and TCP client.而且小测试程序能够成功,和我的测试程序的差别也就在这一点了,因此接受连接和发起连接的端口分开即可。 其他资料: 这个...
  • 2. Server 端的动态名为 RC32s.dll/RC64s.dll,负责接收Client端的请求并应答返回。 Client 端由三大类组成:Connection类、Command类和Fields类 1. Connection类主要负责与Server端的通讯和应答返回值的分发; 2...
  • FTP Server 文件服务 FTP Server FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中应用层的协议之一,作用主要是提供文件共享服务 控制端口 command 21/tcp 数据端口 data 20/tcp FTP ...
  • not allow reuse of same local port for both TCP server and TCP client.而且小测试程序能够成功,和我的测试程序的差别也就在这一点了,因此接受连接和发起连接的端口分开即可。 其他资料: 这个是捣乱...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 137
精华内容 54
关键字:

linuxtcpserver库

linux 订阅