【问题标题】:Connection failed socket in CC中的连接失败套接字
【发布时间】:2015-06-02 22:42:58
【问题描述】:

我正在尝试创建一个与自身连接的程序。 我触发了一个线程客户端和一个线程服务器,并为每个线程创建了一个套接字。我使用相同的端口。

当线程客户端尝试连接线程服务器时,连接失败。为什么?我无法理解。帮帮我!

完整的代码很复杂,因为它很大。但我会概括一下。

#define ADDR "127.0.0.1"

struct threadData{
    int portnum;
    int sockid;
    int lastID;
    unsigned int lastCheck;
};

// ----------- ----- Connection ------ ------------- //

void dieError(char *message, int socket){
    printf("%s\n", message);
    if(socket != 0)
        close(socket);
    exit(1);
}

int createSocket(int portnum, struct sockaddr_in* netw){
    int sockid;

    sockid = socket(AF_INET, SOCK_STREAM, 0);
    if(sockid == -1)
        dieError("socket() failed", sockid);

    struct in_addr addrr;
    if(inet_pton(AF_INET, ADDR, &addrr) < 1)
        dieError("pton() failed", sockid);

    netw->sin_family = AF_INET;
    netw->sin_port = htons(portnum);
    netw->sin_addr = addrr;

    return sockid;
}

void listenSocket(struct threadData* thd, struct sockaddr_in* netw){

    if(bind(thd->sockid, (struct sockaddr *) netw, sizeof(struct sockaddr)) == -1)
        dieError("bind() failed", thd->sockid);

    if(listen(thd->sockid, 0) == -1)
        dieError("listen() failed", thd->sockid);
}

int acceptConnection(int sockid, struct sockaddr* addrr){
    socklen_t cLen = sizeof(struct sockaddr);
    int cSocket = accept(sockid, addrr, &cLen);

    if(cSocket == -1)
        dieError("accept() failed", sockid);

    return cSocket;
}

int createConnection(int portnum, struct sockaddr_in* netw){
    int sockid = createSocket(portnum, netw);

    fcntl(sockid, F_SETFL, O_NONBLOCK);

    if(connect(sockid, (struct sockaddr *) netw, sizeof(struct sockaddr)) == -1)
        dieError("connect() failed", sockid);

    return sockid;
}

// ----------- ----- ---------- ------ ------------- //

//Receptor thread
void * verifyPort(void * param){
    struct threadData* thd = param;
    int cSocket;
    struct sockaddr addrr;
    struct sockaddr_in* netw = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));

    thd->sockid = createSocket(thd->portnum, netw);
    listenSocket(thd, netw);
    cSocket = acceptConnection(thd->sockid, &addrr);
}

//Sender thread
void verifyKeyboard(int portnum){
    int sockid;
    struct sockaddr_in* netw = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
    sockid = createConnection(portnum, netw);
}

// ----------- ---- -------- ------- ------------- //

int main(int argc, char **argv){
    pthread_t tid;
    struct threadData* thd;
    thd = (struct threadData*) malloc(sizeof(struct threadData));

    thd->portnum = atoi(argv[1]);
    thd->lastID = -1;
    thd->lastCheck = 0;

    pthread_create(&tid, NULL, verifyPort, thd);

    verifyKeyboard(atoi(argv[1]));

    free(thd);

    return 0;
}

【问题讨论】:

  • 可能值得用strerror(errno) 打印错误消息(strerror&lt;string.h&gt; 中定义,errno&lt;errno.h&gt; 中定义)
  • 可能完整的代码会有所帮助。
  • 失败怎么办?连接失败?超时?什么也没做?重置了吗?
  • 这看起来很可疑:if(listen(thd-&gt;sockid, 0) == -1) 一个最大长度为零的待处理连接的积压队列?
  • 请删除这个无用的问题。没有明确的问题陈述,也没有对您的解决方案的任何解释。

标签: c sockets pthreads


【解决方案1】:

在我看来,您将错误大小的地址结构传递给客户端线程中的connect()。这个:

if (connect(sockid, addrr, sizeof(struct sockaddr)) == -1)

应该是:

if (connect(sockid, addrr, sizeof(struct sockaddr_in)) == -1)

表示您将 Internet 地址传递给 connect()sizeof(struct sockaddr) 显然是错误的,因为那只是通用结构类型。

如果没有更多代码,很难查明其他问题。

【讨论】:

  • 我修复了我写错的代码,但是 connect() 的地址结构的大小是 strcut sockaddr。 ``` int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); ```http://man7.org/linux/man-pages/man2/connect.2.html
  • @Jeff sockaddr 是各种地址族特定结构的伞形类型。它的大小可能小于或大于 sockaddr_in 等实际地址结构,否则根本不需要 addrlen。
  • @Jeff:Filipe 是对的,您需要将connect() 传递给您传递的实际套接字地址结构的大小,在本例中为sizeof *netw。考虑一下,如果你总是必须通过它sizeof(struct sockaddr),你为什么需要通过它?
  • 我解决了这个问题。就是因为这个fcntl(sockid, F_SETFL, O_NONBLOCK);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
相关资源
最近更新 更多