RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 673627
Accepted
xperious
xperious
Asked:2020-06-01 07:55:30 +0000 UTC2020-06-01 07:55:30 +0000 UTC 2020-06-01 07:55:30 +0000 UTC

套接字上的包装器抛出异常

  • 772

你好,我决定在 c 套接字上写一个小包装器,告诉我为什么 sigpipe 在写函数中崩溃?

套接字.hpp

#ifndef SOCKET_HPP
#define SOCKET_HPP


#include <iostream>
#include <vector>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <strings.h>

enum class socket_type {
    client,
    server,
};


class ISocket {
public:
    ISocket() = default;
    virtual ~ISocket() = default;

    virtual void connect() = 0;
    virtual void close() = 0;

    virtual void receive(char* buff, std::size_t len) = 0;
    virtual void receive(std::vector<char>& buff, std::size_t len) = 0;
    virtual void send(char* buff, std::size_t len) = 0;
    virtual void send(std::vector<char> &buff, std::size_t len) = 0;

protected:
    virtual void bind() = 0;
    virtual void accept() = 0;
    virtual void listen() = 0;

    virtual int getdescriptor() = 0;
};

class serv_socket : public ISocket {
public:
    // у серверного сокета должен быть порт
    serv_socket(int port);
    ~serv_socket() = default;

    virtual void connect() final;
    virtual void close() final;

    virtual void receive(char *buff, std::size_t len) final;
    virtual void receive(std::vector<char> &buff, std::size_t len) final;
    virtual void send(char *buff, std::size_t len) final;
    virtual void send(std::vector<char> &buff, std::size_t len) final;

protected:
    virtual void bind() final;
    virtual void accept() final;
    virtual void listen() final;

    virtual int getdescriptor() final;

private:
    //дескриптор сокета который прослушиваем
    int descriptor;
    // дескриптор сокета к которому accept-имся
    int newdescriptor;
    // адрес сокета который прослушиваем
    struct sockaddr_in addr;
    // адрес сокета к которому accept-имся
    struct sockaddr cli_addr;
    //
    socklen_t clilen;
    // тип сокета
    socket_type type;
};

class client_socket : public ISocket {
public:
    client_socket(char * const address, int port);
    ~client_socket() = default;

    virtual void connect() final;
    virtual void close() final;

    virtual void receive(char* buff, std::size_t len) final;
    virtual void receive(std::vector<char> &buff, std::size_t len) final;
    virtual void send(char *buff, std::size_t len) final;
    virtual void send(std::vector<char> &buff, std::size_t len) final;


protected:
    virtual void bind() final;
    virtual void accept() final;
    virtual void listen() final;

    virtual int getdescriptor() final;

private:
    //дескриптор сокета
    int descriptor;
    //характеристики сокета
    struct sockaddr_in serv_addr;
    // хост
    struct hostent *server;
    // тип сокета
    socket_type type;
};

#endif // SOCKET_HPP

套接字.cpp:

#include <socket.hpp>
#include <vector>
#include <netdb.h>

serv_socket::serv_socket(int port)
    : ISocket(),
      descriptor(0),
      newdescriptor(0),
      type(socket_type::server)
{
    descriptor = ::socket(AF_INET, SOCK_STREAM, 0);
    bzero((char *) &addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);
}

void serv_socket::bind() {
    if(::bind(descriptor,
              (struct sockaddr *) &addr,
              sizeof(addr)) < 0
    )
        log_("ERROR in bind socket");
}

void serv_socket::listen()
{
    ::listen(descriptor, 5);
}

void serv_socket::accept()
{
    clilen = sizeof(cli_addr);
    newdescriptor = ::accept(descriptor,
                     (struct sockaddr *) &cli_addr,
                     &clilen);
}

void serv_socket::close() {
    ::close(newdescriptor);
    ::close(descriptor);
}

void serv_socket::receive(std::vector<char>& buff, std::size_t len) {
    int n = ::read(newdescriptor, buff.data(), len);
    if(n < 0)
        log_("ERROR reading from socket");
}

void serv_socket::receive(char *buff, std::size_t len) {
    int n = ::read(newdescriptor, buff, len);
    if(n < 0)
        log_("ERROR reading from socket");
}

void serv_socket::send(std::vector<char>& buff, std::size_t len) {
    int n = ::write(newdescriptor, buff.data(), len);
}

void serv_socket::send(char *buff, std::size_t len) {
    int n = ::write(newdescriptor, buff, len);
}

void serv_socket::connect()
{
    bind();
    listen();
    accept();
}

int serv_socket::getdescriptor() {
    return descriptor;
}

// ------------------клиентский сокет

client_socket::client_socket(char* const address, int port)
    : ISocket(),
      descriptor(0),
      type(socket_type::client)
{
    // создаем сокет
    descriptor = socket(AF_INET, SOCK_STREAM, 0);
    // устанавливаем адрес сервера
    server = gethostbyname(address);
    if(server == nullptr)
        log_("ERROR");
    //
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(port);
}

void client_socket::connect() {
    if (::connect(descriptor,
                  (struct sockaddr *)&serv_addr,
                  sizeof(serv_addr)) < 0
        )
            log_("ERROR connecting");
}

void client_socket::close() {
    ::close(descriptor);
}

void client_socket::receive(std::vector<char> &buff, std::size_t len) 
{
    int n = ::read(descriptor, buff.data(), len);
    if(n < 0)
        log_("ERROR reading from socket");
}

void client_socket::receive(char* buff, std::size_t len) {
    int n = ::read(descriptor, buff, len);
    if(n < 0)
        log_("ERROR reading from socket");
}

void client_socket::send(std::vector<char>& buff, std::size_t len) {
    int n = ::write(descriptor, buff.data(), len);
}

void client_socket::send(char* buff, std::size_t len) {
    int stop = 0;
    int n = ::write(descriptor, buff, len);     <<---------------вот тут вылетает sigpipe
}

void client_socket::bind() {

}

void client_socket::accept() {

}

void client_socket::listen() {

}

int client_socket::getdescriptor() {
    return descriptor;
}

主.cpp:

int main(int argc, char** argv) {

    client_socket cs("127.0.0.1", 80);
    cs.connect();
    cs.send("hello", 6);
    cs.close();
    return 0;
}
c++
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    xperious
    2020-06-02T05:41:49Z2020-06-02T05:41:49Z

    一般来说,sigpipe 由于发送到一个不存在的连接而匆忙......更正了使用 MSG_NOSIGNAL 标志发送的写入并停止接收 sigpipe ...并且不存在的连接是由于二进制文件不是从root,但是不能绑定到小于 1024 套接字的用户端口(不是 root)...将端口更改为 1200,一切都很好

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5