小编Ric*_*Liu的帖子

如何在进行多个连接时在C中设置套接字超时?

我正在写一个简单的程序,它可以与不同的服务器建立多个连接以进行状态检查.所有这些连接都是按需构建的; 最多可同时创建10个连接.我不喜欢单线程每插槽的想法,所以我将所有这些客户端套接字非阻塞,并将它们扔进select()池.

它工作得很好,直到我的客户抱怨等待时间太久才能在目标服务器停止响应时获得错误报告.

我已在论坛中查看了几个主题.有人建议可以使用alarm()信号或在select()函数调用中设置超时.但我正在处理多个连接,而不是一个连接.当进程范围超时信号发生时,我无法区分所有其他连接之间的超时连接.

无论如何都要更改系统默认超时持续时间?

c sockets linux

61
推荐指数
4
解决办法
17万
查看次数

在使用工厂模式时,我应该以任何方式避免向下转型吗?

我正在开发一个实现专有协议的服务器项目。服务器是用C++实现的工厂模式,我们现在面临着向下转型的问题。

我正在研究的协议是为自动控制慢速网络而设计的,例如RS485、ZigBee、窄带PLC 等。我们设计了工厂模式的主服务器。当接收到新帧时,我们首先识别该帧的关联设备类型,调用工厂方法生成新的“解析器”实例,并将帧分派给解析器实例。

我们的专有协议是纯二进制实现的,我们可能需要的每一个信息都记录在帧本身中,因此可以尽可能简单地定义基本接口。我们还将为我们的工厂实现自动注册方法(此处省略了与 std::map 操作相关的详细代码):

// This is our "interface" base-class
class parser
{
public:
    virtual int parse(unsigned char *) = 0;
    virtual ~parser() { }
};

// The next two classes are used for factory pattern
class instance_generator
{
public:
    virtual parser *generate() = 0;
};

class parser_factory
{
private:
    static std::map<int,instance_generator*> classDB;
public:
    static void add(int id, instance_generator &genrator);
    parser *get_instance(int id);
};

// the two template classes are implementations of "auto-regisrtation"
template <class G, int ID> …
Run Code Online (Sandbox Code Playgroud)

c++ oop downcast factory-pattern

5
推荐指数
1
解决办法
1438
查看次数

如何按顺序执行不同参数类型的一元函数对象?

我正在设计一种机制,它将按顺序执行一组一元函数对象.这些函数对象在运行时分配,问题是:这些函数对象的参数类型不同.

我想做的是这样的:

class command_sequence {
private:

/* some kind of container */

public:
    void add( FUNC_OBJ &func, PARAM val );
    void run(void);
};

class check_temperature {
public:
    void operator() (int celsius) {
        if(celsius > 26) {
            cooler.switch_on();
        }
    }
};

class log_usage {
public:
    void operator() (std::string username) {
        username.append(" logged in");
        syslog(LOG_NOTICE,username.c_str());
    }
};

command_sequence sequence;
log_usage logger;
check_temperature checker;

sequence.add(logger, std::string("administrator"));
sequence.add(checker, lobbyMeter.read_temperature());
sequence.add(logger, std::string("lecture"));
sequence.add(checker, classroomMeter.read_temperature());
sequence.run();
Run Code Online (Sandbox Code Playgroud)

如果我正在编写C代码,我别无选择只能将void*作为参数的回调函数指针.但我现在正在使用C++,应该有一种优雅的方式来处理它.

我现在能想到的最好方法是声明一个虚拟继承自抽象包装类的模板类:

class command_sequence {
private:

    class runner {
    public: …
Run Code Online (Sandbox Code Playgroud)

c++ function-object

5
推荐指数
2
解决办法
797
查看次数

当本地关闭套接字时,poll()无法检测到事件?

我正在开发一个项目,将TCP/IP客户端程序移植到嵌入式ARM-Linux控制器板上.客户端程序最初是用epoll()编写的.但是,目标平台已经很老了; 唯一可用的内核是2.4.x,不支持epoll().所以我决定在poll()中重写I/O循环.

但是当我测试代码时,我发现poll()没有按照我的预期行事:当一个TCP/IP客户端套接字在本地由另一个线程关闭时,它不会返回.我写了一个非常简单的代码来做一些测试:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h>

struct pollfd   fdList[1];

void *thread_runner(void *arg)
{
    sleep(10);
    close(fdList[0].fd);
    printf("socket closed\n");
    pthread_exit(NULL);
}

int main(void)
{
    struct  sockaddr_in hostAddr;
    int sockFD;
    char buf[32];
    pthread_t handle;

    sockFD = socket(AF_INET, SOCK_STREAM, 0);
    fcntl(sockFD,F_SETFL,O_NONBLOCK|fcntl(sockFD,F_GETFL,0));

    inet_aton("127.0.0.1",&(hostAddr.sin_addr));
    hostAddr.sin_family = AF_INET;
    hostAddr.sin_port  = htons(12345);
    connect(sockFD,(struct sockaddr *)&hostAddr,sizeof(struct sockaddr));

    fdList[0].fd = sockFD;
    fdList[0].events = POLLOUT;

    pthread_create(&handle,NULL,thread_runner,NULL);

    while(1) {
        if(poll(fdList,1,-1) < 1) {
            continue;
        }
        if(fdList[0].revents & POLLNVAL ) …
Run Code Online (Sandbox Code Playgroud)

sockets linux

4
推荐指数
1
解决办法
5609
查看次数

标签 统计

c++ ×2

linux ×2

sockets ×2

c ×1

downcast ×1

factory-pattern ×1

function-object ×1

oop ×1