1

我有 3 个套接字侦听来自同一 IP(10080、20081、30082)的不同端口。我已经在不同的线程(实际上是 pthreads)中创建了套接字并绑定了它等等。当我执行 Accept() 时,3 个套接字等待客户端调用,但是当我对任何端口进行调用时,总是回答发出最后一个 Accept() 的套接字。

这是我的过程(C++):

线程 1

为端口 10080 创建套接字

为端口 10080 绑定套接字

监听 10080 端口

接受端口 10080

..................................................... .....................

线程 2

为端口 20081 创建套接字

为端口 20081 绑定套接字

监听 20081 端口

接受端口 20081

..................................................... .....................

线程 3

为端口 30082 创建套接字

为端口 30082 绑定套接字

监听 30082 端口

接受端口 30082

..................................................... .....................

不管我调用哪个端口(10080、20081 或 30082)总是继续处理“线程 3”。

任何人都可以帮助我处理正确线程中的信息吗?

谢谢。

PS:我正在监视主套接字中的端口以及Accept()指令创建的套接字中的端口,并且主套接字仍然正确(30082)并且Accept套接字具有被调用端口(10080、20081或30082 )。

struct addrinfo lRequestAddrInfo;
struct addrinfo * lResultAddrInfo;
int lSocketOption = 1;

memset(&lRequestAddrInfo,0,sizeof(lRequestAddrInfo));
lRequestAddrInfo.ai_socktype=SOCK_STREAM;
lRequestAddrInfo.ai_flags=AI_PASSIVE;
int lReturn = 0;

lReturn = getaddrinfo(lAddress->ip.c_str(), lAddress->port.c_str(), &lRequestAddrInfo, &lResultAddrInfo);

int lSocket = socket(lResultAddrInfo->ai_family, SOCK_STREAM, lResultAddrInfo->ai_protocol);
setsockopt(lSocket, SOL_SOCKET, SO_REUSEADDR, &lSocketOption, sizeof(lSocketOption));
lReturn = bind(lSocket, lResultAddrInfo->ai_addr, lResultAddrInfo->ai_addrlen);
lReturn = listen(lSocket, SOMAXCONN);
while(IsConnected())
{
    struct sockaddr lSocketAddress;
    socklen_t lSocketAddresslen = sizeof(lSocketAddress);
    lNewSocket = accept(pListener->_connection, &lSocketAddress, &lSocketAddresslen);

    if (lNewSocket > -1)
    {
        //process information in new thread
    }   
}

这是线程内部的代码。更多信息:

线程 1

lSocket = 3(端口 10080)

线程 2

lSocket = 5(端口 20081)

线程 3

lSocket = 7(端口 30082)

当我在 10080 港口停靠时

lSocket = 7(端口 30082) lNewSocket = 4(端口 10080)

当我在 20081 港口停靠时

lSocket = 7(端口 30082) lNewSocket = 6(端口 20081)

当我在 30082 港口停靠时

lSocket = 7(端口 30082) lNewSocket = 8(端口 30082)

4

2 回答 2

0

我认为您错过了代码的重要部分。因为你没有包含它,所以很难判断你是否使用了 FD_SET()、FD_ISSET() 和朋友。如果不是,那么肯定会得到奇怪的结果。我认为粘贴代码比用文字解释更容易。这就是类似的事情对我有用的方式:

socket_descriptor=bindsock(thd);
while(true) {
        fd_set      rfs, wfs;
        FD_ZERO(&rfs);
        FD_ZERO(&wfs);

        FD_SET(socket_descriptor,&rfs);
        maxfd = conn_select(thd,&rfs, &wfs);

        if (select(maxfd + 1, &rfs, &wfs, NULL, NULL) == -1) {
            if (errno == EINTR) {
                continue;
            }
            break;
        }
        if (FD_ISSET(socket_descriptor, &rfs)) {
            thd->client_fd = accept(socket_descriptor, &thd->cliaddr,&clilen);

……

和函数内部:

int
conn_select(struct THD*thd,fd_set * rfs, fd_set * wfs) {
    int maxfd = -1;
    size_t i;
    DBUG_ENTER("conn_cullselect");

    if (vector == NULL) {
        DBUG_PRINT("info",("vector == NULL"));
        DBUG_RETURN(0);
    }

    for (i = 0; i < MAX_CONNECTIONS; i++) {
        conn_t     *v;

        if (vector[i] == NULL) {
            DBUG_PRINT("info",("continue"));
            continue;
        }
        v = vector[i];
        switch (v->state) {
            case AWAITING_REQUEST:
                DBUG_PRINT("info",("AWAITING_REQUEST"));
                if (maxfd < v->sd) {
                    maxfd = v->sd;
                }
                FD_SET(v->sd, rfs);
                break;
            case SENDING_FILE:
                DBUG_PRINT("info",("SENDING_FILE"));
                if (maxfd < v->fd) {
                    maxfd = v->fd;
                }
                FD_SET(v->fd, rfs);
                break;
            case SENDING_HEADER:
                DBUG_PRINT("info",("SENDING_HEADER"));
                if (maxfd < v->sd) {
                    maxfd = v->sd;
                }
                FD_SET(v->sd, wfs);
                break;
        }
    }
    DBUG_PRINT("info",("returning %d from conn_cullselect",maxfd));
    DBUG_RETURN(maxfd);
}

想法是一样的,而不取决于你正在监听多少个端口。

于 2012-06-08T09:12:23.490 回答
0

最后我做到了!我在线程外编写了套接字创建和侦听操作,并在线程编写了接受操作。

我希望这对其他人有帮助!

感谢大家的回答!

于 2012-06-12T10:26:38.337 回答