BUFFER之二(37)

来源:互联网 发布:集合java 编辑:程序博客网 时间:2024/06/09 16:47

应用程序想关闭连接,但是可能正处于发送数据的过程中,output buffer中有数据还没有发送完
不能直接调用close

conn->send(buff)
conn->shutdown()

POLLOUT事件
关闭写的这一半
连接状态更改为kDisconnection,并没有关闭连接

服务器主动断开与客户端的连接
这意味着 客户端 read返回0
close(conn)

POLLHUP|POLLIN


如果是客户端主动关闭连接,那么服务器端只返回POLLIN
如果是服务器端主动关闭,然后客户端再关闭,那么服务器端返回POLLIN和POLLHUP事件




测试程序

服务器

#include <muduo/net/TcpServer.h>#include <muduo/net/EventLoop.h>#include <muduo/net/InetAddress.h>#include <boost/bind.hpp>#include <stdio.h>using namespace muduo;using namespace muduo::net;class TestServer{ public:  TestServer(EventLoop* loop,             const InetAddress& listenAddr)    : loop_(loop),      server_(loop, listenAddr, "TestServer")  {    server_.setConnectionCallback(        boost::bind(&TestServer::onConnection, this, _1));    server_.setMessageCallback(        boost::bind(&TestServer::onMessage, this, _1, _2, _3));    message1_.resize(100);    message2_.resize(200);    std::fill(message1_.begin(), message1_.end(), 'A');    std::fill(message2_.begin(), message2_.end(), 'B');  }  void start()  {      server_.start();  } private:  void onConnection(const TcpConnectionPtr& conn)  {    if (conn->connected())    {      printf("onConnection(): new connection [%s] from %s\n",             conn->name().c_str(),             conn->peerAddress().toIpPort().c_str());      conn->send(message1_);      conn->send(message2_);      conn->shutdown();    }    else    {      printf("onConnection(): connection [%s] is down\n",             conn->name().c_str());    }  }  void onMessage(const TcpConnectionPtr& conn,                 Buffer* buf,                 Timestamp receiveTime)  {    muduo::string msg(buf->retrieveAllAsString());    printf("onMessage(): received %zd bytes from connection [%s] at %s\n",           msg.size(),           conn->name().c_str(),           receiveTime.toFormattedString().c_str());    conn->send(msg);  }  EventLoop* loop_;  TcpServer server_;  muduo::string message1_;  muduo::string message2_;};int main(){  printf("main(): pid = %d\n", getpid());  InetAddress listenAddr(8888);  EventLoop loop;  TestServer server(&loop, listenAddr);  server.start();  loop.loop();}



客户端

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h> //该程序可能出现粘包问题#define ERR_EXIT(m) \        do \        { \                perror(m); \                exit(EXIT_FAILURE); \        } while(0)int main(void){    int sock;    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)        ERR_EXIT("socket");    struct sockaddr_in servaddr;    memset(&servaddr, 0, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(8888);    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");    if (connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)        ERR_EXIT("connect");    char buf[1024] ={0};    while (1)    {        int ret = read(sock, buf, sizeof(buf));        printf("ret=%d\n", ret);        if (ret == 0)            break;        fputs(buf, stdout);        fflush(stdout);        memset(buf, 0, sizeof(buf));    }    sleep(10);    close(sock);    return 0;}



程序输出

服务器:

ubuntu@ubuntu-virtual-machine:~/pro/37$ ./build/debug/bin/reactor_test12 main(): pid = 868320131024 07:19:37.457271Z  8683 TRACE updateChannel fd = 4 events = 3 - EPollPoller.cc:10420131024 07:19:37.457470Z  8683 TRACE EventLoop EventLoop created 0xBFDDAB44 in thread 8683 - EventLoop.cc:6220131024 07:19:37.457485Z  8683 TRACE updateChannel fd = 5 events = 3 - EPollPoller.cc:10420131024 07:19:37.457645Z  8683 TRACE updateChannel fd = 6 events = 3 - EPollPoller.cc:10420131024 07:19:37.457661Z  8683 TRACE loop EventLoop 0xBFDDAB44 start looping - EventLoop.cc:9420131024 07:19:47.468016Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:19:57.478500Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:20:07.488977Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:20:17.499503Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:20:27.509985Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:20:37.520451Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:20:47.528439Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:20:57.538942Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:21:01.262358Z  8683 TRACE poll 1 events happended - EPollPoller.cc:6520131024 07:21:01.262792Z  8683 TRACE printActiveChannels {6: IN }  - EventLoop.cc:25720131024 07:21:01.262820Z  8683 TRACE handleEventWithGuard 2222222222222222POLLIN22222222222222222222 - Channel.cc:8920131024 07:21:01.262881Z  8683 INFO  TcpServer::newConnection [TestServer] - new connection [TestServer:0.0.0.0:8888#1] from 127.0.0.1:56659 - TcpServer.cc:9320131024 07:21:01.262916Z  8683 DEBUG TcpConnection TcpConnection::ctor[TestServer:0.0.0.0:8888#1] at 0x96C65D0 fd=8 - TcpConnection.cc:6220131024 07:21:01.262934Z  8683 TRACE newConnection [1] usecount=1 - TcpServer.cc:11120131024 07:21:01.262961Z  8683 TRACE newConnection [2] usecount=2 - TcpServer.cc:11320131024 07:21:01.262981Z  8683 TRACE connectEstablished [3] usecount=6 - TcpConnection.cc:23120131024 07:21:01.262998Z  8683 TRACE updateChannel fd = 8 events = 3 - EPollPoller.cc:104onConnection(): new connection [TestServer:0.0.0.0:8888#1] from 127.0.0.1:5665920131024 07:21:01.263363Z  8683 TRACE connectEstablished [4] usecount=6 - TcpConnection.cc:23620131024 07:21:01.263378Z  8683 TRACE newConnection [5] usecount=2 - TcpServer.cc:12220131024 07:21:11.265287Z  8683 TRACE poll 1 events happended - EPollPoller.cc:6520131024 07:21:11.265469Z  8683 TRACE printActiveChannels {8: IN HUP }  - EventLoop.cc:25720131024 07:21:11.265483Z  8683 TRACE handleEvent [6] usecount=2 - Channel.cc:6720131024 07:21:11.265491Z  8683 TRACE handleEventWithGuard 1111111111111111POLLHUP1111111111111111111 - Channel.cc:8520131024 07:21:11.265498Z  8683 TRACE handleEventWithGuard 2222222222222222POLLIN22222222222222222222 - Channel.cc:8920131024 07:21:11.265556Z  8683 TRACE handleClose fd = 8 state = 3 - TcpConnection.cc:29720131024 07:21:11.265567Z  8683 TRACE updateChannel fd = 8 events = 0 - EPollPoller.cc:104onConnection(): connection [TestServer:0.0.0.0:8888#1] is down20131024 07:21:11.265588Z  8683 TRACE handleClose [7] usecount=3 - TcpConnection.cc:30520131024 07:21:11.265604Z  8683 INFO  TcpServer::removeConnectionInLoop [TestServer] - connection TestServer:0.0.0.0:8888#1 - TcpServer.cc:15320131024 07:21:11.265611Z  8683 TRACE removeConnectionInLoop [8] usecount=6 - TcpServer.cc:15720131024 07:21:11.265626Z  8683 TRACE removeConnectionInLoop [9] usecount=5 - TcpServer.cc:15920131024 07:21:11.265639Z  8683 TRACE removeConnectionInLoop [10] usecount=6 - TcpServer.cc:17020131024 07:21:11.265646Z  8683 TRACE handleClose [11] usecount=3 - TcpConnection.cc:30820131024 07:21:11.265652Z  8683 TRACE handleEvent [12] usecount=2 - Channel.cc:6920131024 07:21:11.265659Z  8683 TRACE removeChannel fd = 8 - EPollPoller.cc:14720131024 07:21:11.265682Z  8683 DEBUG ~TcpConnection TcpConnection::dtor[TestServer:0.0.0.0:8888#1] at 0x96C65D0 fd=8 - TcpConnection.cc:6920131024 07:21:21.275816Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:21:31.285830Z  8683 TRACE poll  nothing happended - EPollPoller.cc:7420131024 07:21:41.296314Z  8683 TRACE poll  nothing happended - EPollPoller.cc:74^Cubuntu@ubuntu-virtual-machine:~/pro/37$

客户端:

ubuntu@ubuntu-virtual-machine:~/pro/37$ ./a.out ret=300AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBret=0


原创粉丝点击