1

我正在使用 C++ 开发另一个用于 Linux 的套接字库,作为个人练习。这是我的代码:

#ifndef SOCKET_H
#define SOCKET_H

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;

/**
 * Creates a struct to hold all the necessary information to create a socket.<br/>
 * Typically, you should not need to call this yourself, as it is done when you     call         listen() or dial()
 * @param host The hostname or IP address to connect to.
 * @param service The service on that machine (e.g "http" or "80")
 * @param sock The type of socket ("tcp" or "udp")
 * @return A addrinfo struct with all the required information to create a connection.
 */
addrinfo setup(const char *host,const char *service,const char *sock) {
    struct addrinfo hints;
    struct addrinfo *serv;
cout << "2.call to setup()\n";
//cout << "3.setup() returns here.\n";
//return *serv;
    int status=0;
/*struct addrinfo hints;
    struct addrinfo *serv;*/

    memset(&hints,0,sizeof hints);
    hints.ai_family=AF_UNSPEC;
    if (sock=="tcp") {
    hints.ai_socktype=SOCK_STREAM;
    } else if (sock=="udp") {
        hints.ai_socktype=SOCK_DGRAM;
    } else {
        fprintf(stderr,"[!] xsockets: error: unknown socket type %s\n",sock);
        exit(2);
    }
    hints.ai_flags=AI_PASSIVE;

    if ((status=getaddrinfo(host,service,&hints,&serv))!=0) {
        fprintf(stderr, "[!] xsockets: error: getaddrinfo error: %s\n",     gai_strerror(status));
        exit(1);
    }
    cout << "3.setup() returns here.\n";
    return *serv;
}

/**
 * Listens on a portand returns a scoket file descriptor.
 * @param service The service on this machine (e.g "http" or "80")
 * @param sock The type of socket ("tcp" or "udp")
 * @return A socket filde descriptor.
 */
int listen(const char *service,const char *sock) {
    cout << "1.call to listen()\n";
    struct addrinfo *serv;
    *serv=setup(NULL,service,sock);
    cout << "4.is this ever called?";
    int sockfd=socket(serv->ai_family,serv->ai_socktype,serv->ai_protocol);
    int status=bind(sockfd,serv->ai_addr,serv->ai_addrlen);
    if (status!=0) {
        fprintf(stderr,"[!] xsockets: error: bind error:                         %s\n",gai_strerror(status));
        exit(3);
}
    cout << "5.listen() returns here.";
    return sockfd;
}
#endif

如果我运行它,它会达到 #3 “setup() 返回这里”,但永远不会达到 #4 “这曾经被调用过吗?” 更不用说 #5 “listen() 在这里返回”

谁能告诉我出了什么问题。

我在 Ubuntu Linux 上,以 root 权限运行它。g++它是用命令编译的。

这是我得到的:

4

2 回答 2

3

您有未定义的行为,因为您没有初始化指针serv,而是立即使用*serv.

尽管如此,在调试时,您应该确保通过插入 或 来刷新std::flush输出:std::endlstd::cout

cout << "4.is this ever called?" << std::endl;
于 2013-04-20T22:08:48.450 回答
2

你有一些基本问题:

  1. 您不为serv.

    struct addrinfo *serv;

    *serv=setup(NULL,service,sock);

  2. 您不检查大多数函数的返回值,例如int sockfd.

  3. 您在堆栈上声明事物而不是全局声明,尝试找出每个变量的范围。

    struct addrinfo hints;
    struct addrinfo *serv;
    
于 2013-04-20T22:10:43.747 回答