网络编程-第一种netcat代码解析

#include "Acceptor.h"
#include "InetAddress.h"
#include "TcpStream.h"

#include <thread>

#include <string.h>
#include <unistd.h>

int write_n(int fd, const void* buf, int length)
{
  int written = 0;
  while (written < length)
  {
    int nw = ::write(fd, static_cast<const char*>(buf) + written, length - written);
    if (nw > 0)
    {
      written += nw;
    }
    else if (nw == 0)
    {
      break;  // EOF
    }
    else if (errno != EINTR)
    {
      perror("write");
      break;
    }
  }
  return written;
}

void run(TcpStreamPtr stream)
{
  // Caution: a bad example for closing connection
  std::thread thr([&stream] () {
    char buf[8192];
    int nr = 0;
    // 接收stdin(输入缓冲区)数据,发送给服务器
    while ( (nr = stream->receiveSome(buf, sizeof(buf))) > 0)
    {
      int nw = write_n(STDOUT_FILENO, buf, nr);
      if (nw < nr)
      {
        break;
      }
    }
    ::exit(0);  // should somehow notify main thread instead
  });

  //接收服务器信息,接收后输出到stdout(输出缓冲区)
  char buf[8192];
  int nr = 0;
  while ( (nr = ::read(STDIN_FILENO, buf, sizeof(buf))) > 0)
  {
    int nw = stream->sendAll(buf, nr);
    if (nw < nr)
    {
      break;
    }
  }
  stream->shutdownWrite();
  thr.join();
}

int main(int argc, const char* argv[])
{
  if (argc < 3)
  {
    printf("Usage:\n  %s hostname port\n  %s -l port\n", argv[0], argv[0]);
    return 0;
  }

  int port = atoi(argv[2]);
  // 服务器-l
  if (strcmp(argv[1], "-l") == 0)
  {
    std::unique_ptr<Acceptor> acceptor(new Acceptor(InetAddress(port)));
    TcpStreamPtr stream(acceptor->accept());
    if (stream)
    {
      acceptor.reset();  // stop listening
      run(std::move(stream));
    }
    else
    {
      perror("accept");
    }
  }
  else //客户端
  {
    InetAddress addr(port);
    const char* hostname = argv[1];
    if (InetAddress::resolve(hostname, &addr))
    {
      TcpStreamPtr stream(TcpStream::connect(addr));
      if (stream)
      {
        run(std::move(stream));
      }
      else
      {
        printf("Unable to connect %s\n", addr.toIpPort().c_str());
        perror("");
      }
    }
    else
    {
      printf("Unable to resolve %s\n", hostname);
    }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值