C++ socket通信遇到的问题及解决方法

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  class NtripServer {

  public:

  NtripServer() : socket_fd_(-1), thread_is_running_(false), service_is_running_(false) {}

  ~NtripServer() {}

  void Start() {

  if (service_is_running_) {

  std::cout << "Service is already running!" << std::endl;

  return;

  }

  // 创建socket

  socket_fd_ = socket(AF_INET, SOCK_STREAM, 0);

  if (socket_fd_ == -1) {

  std::cout << "Failed to create socket!" << std::endl;

  return;

  }

  // 设置socket选项

  int optval = 1;

  setsockopt(socket_fd_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

  // 绑定地址和端口

  sockaddr_in server_addr{};

  server_addr.sin_family = AF_INET;

  server_addr.sin_port = htons(1234);

  server_addr.sin_addr.s_addr = INADDR_ANY;

  if (bind(socket_fd_, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {

  std::cout << "Failed to bind address!" << std::endl;

  close(socket_fd_);

  socket_fd_ = -1;

  return;

  }

  // 监听连接

  if (listen(socket_fd_, 5) == -1) {

  std::cout << "Failed to listen!" << std::endl;

  close(socket_fd_);

  socket_fd_ = -1;

  return;

  }

  // 启动线程处理连接

  service_is_running_ = true;

  std::thread thread(&NtripServer::ThreadHandler, this);

  thread.detach();

  }

  void Stop() {

  if (!service_is_running_) {

  std::cout << "Service is not running!" << std::endl;

  return;

  }

  service_is_running_ = false;

  }

  private:

  int socket_fd_;

  bool thread_is_running_;

  bool service_is_running_;

  void ThreadHandler() {

  int ret;

  char recv_buffer[1024] = {};

  thread_is_running_ = true;

  // 将socket_fd_设置为非阻塞模式

  if (SetNonBlocking(socket_fd_) == -1) {

  std::cout << "Failed to set socket to non-blocking mode" << std::endl;

  return;

  }

  while (thread_is_running_) {

  ret = recv(socket_fd_, recv_buffer, sizeof(recv_buffer), 0);

  if (ret == 0) {

  std::cout << "Remote socket close!!!" << std::endl;

  break;

  } else if (ret < 0) {

  if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {

  std::cout << "Remote socket error!!!" << std::endl;

  break;

  }

  } else {

  // 处理接收到的数据

  std::cout << "Received data: " << recv_buffer << std::endl;

  }

  std::this_thread::sleep_for(std::chrono::milliseconds(10));

  }

  close(socket_fd_);

  socket_fd_ = -1;

  thread_is_running_ = false;

  service_is_running_ = false;

  }

  int SetNonBlocking(int socket_fd) {

  int flags = fcntl(socket_fd, F_GETFL, 0);

  if (flags == -1) {

  return -1;

  }

  if (fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK) == -1) {

  return -1;

  }

  return 0;

  }

  };

  int main() {

  NtripServer server;

  server.Start();

  // 服务运行一段时间后停止

  std::this_thread::sleep_for(std::chrono::seconds(10));

  server.Stop();

  return 0;

  }