thrift0.8.0支持win7的方法

来源:互联网 发布:知乎 回复评论 编辑:程序博客网 时间:2024/06/06 00:51

thrift0.8.0不支持Win7环境(XP没试过)。要想开启支持,必须修改thrift的源代码。

修改的代码如下

void TServerSocket::listen() {#ifdef _WIN32    WSADATA wsa_data;    WSAStartup(MAKEWORD(2, 2), &wsa_data);#endif  int sv[2];  if (-1 == socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {    GlobalOutput.perror("TServerSocket::listen() socketpair() ", errno);    intSock1_ = -1;    intSock2_ = -1;  } else {    intSock1_ = sv[1];    intSock2_ = sv[0];  }  struct addrinfo hints, *res, *res0;  int error;  char port[sizeof("65536") + 1];  std::memset(&hints, 0, sizeof(hints));#ifdef _WIN32  hints.ai_family = PF_INET;  hints.ai_socktype = SOCK_STREAM;  hints.ai_flags = 0;//AI_PASSIVE | AI_ADDRCONFIG;#else  hints.ai_family = PF_UNSPEC;  hints.ai_socktype = SOCK_STREAM;  hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;#endif  sprintf(port, "%d", port_);  // Wildcard address  error = getaddrinfo(NULL, port, &hints, &res0);  if (error) {    GlobalOutput.printf("getaddrinfo %d: %s", error, gai_strerror(error));    close();    throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for server socket.");  }  // Pick the ipv6 address first since ipv4 addresses can be mapped  // into ipv6 space.  for (res = res0; res; res = res->ai_next) {    if (res->ai_family == AF_INET6 || res->ai_next == NULL)      break;  }  if (! path_.empty()) {#ifdef _WIN32      serverSocket_ = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);#else    serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP);#endif  } else {    serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);  }  if (serverSocket_ == -1) {    int errno_copy = errno;    GlobalOutput.perror("TServerSocket::listen() socket() ", errno_copy);    close();    throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy);  }  // Set reusaddress to prevent 2MSL delay on accept  int one = 1;  if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_REUSEADDR,                       cast_sockopt(&one), sizeof(one))) {    int errno_copy = errno;    GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_REUSEADDR ", errno_copy);    close();    throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_REUSEADDR", errno_copy);  }  // Set TCP buffer sizes  if (tcpSendBuffer_ > 0) {    if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_SNDBUF,                         cast_sockopt(&tcpSendBuffer_), sizeof(tcpSendBuffer_))) {      int errno_copy = errno;      GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy);      close();      throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", errno_copy);    }  }  if (tcpRecvBuffer_ > 0) {    if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_RCVBUF,                         cast_sockopt(&tcpRecvBuffer_), sizeof(tcpRecvBuffer_))) {      int errno_copy = errno;      GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy);      close();      throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", errno_copy);    }  }  // Defer accept  #ifdef TCP_DEFER_ACCEPT  if (-1 == setsockopt(serverSocket_, SOL_SOCKET, TCP_DEFER_ACCEPT,                       &one, sizeof(one))) {    int errno_copy = errno;    GlobalOutput.perror("TServerSocket::listen() setsockopt() TCP_DEFER_ACCEPT ", errno_copy);    close();    throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_DEFER_ACCEPT", errno_copy);  }  #endif // #ifdef TCP_DEFER_ACCEPT  #ifdef IPV6_V6ONLY  if (res->ai_family == AF_INET6 && path_.empty()) {    int zero = 0;    if (-1 == setsockopt(serverSocket_, IPPROTO_IPV6, IPV6_V6ONLY,           cast_sockopt(&zero), sizeof(zero))) {      GlobalOutput.perror("TServerSocket::listen() IPV6_V6ONLY ", errno);    }  }  #endif // #ifdef IPV6_V6ONLY  // Turn linger off, don't want to block on calls to close  struct linger ling = {0, 0};  if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER,                       cast_sockopt(&ling), sizeof(ling))) {    int errno_copy = errno;    GlobalOutput.perror("TServerSocket::listen() setsockopt() SO_LINGER ", errno_copy);    close();    throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy);  }  // Unix Sockets do not need that  if (path_.empty()) {    // TCP Nodelay, speed over bandwidth    if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY,                         cast_sockopt(&one), sizeof(one))) {      int errno_copy = errno;      GlobalOutput.perror("TServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy);      close();      throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy);    }  }  // Set NONBLOCK on the accept socket  int flags = fcntl(serverSocket_, F_GETFL, 0);  if (flags == -1) {    int errno_copy = errno;    GlobalOutput.perror("TServerSocket::listen() fcntl() F_GETFL ", errno_copy);    throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);  }  if (-1 == fcntl(serverSocket_, F_SETFL, flags | O_NONBLOCK)) {    int errno_copy = errno;    GlobalOutput.perror("TServerSocket::listen() fcntl() O_NONBLOCK ", errno_copy);    throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);  }  // prepare the port information  // we may want to try to bind more than once, since SO_REUSEADDR doesn't  // always seem to work. The client can configure the retry variables.  int retries = 0;  if (! path_.empty()) {#ifndef _WIN32    // Unix Domain Socket    struct sockaddr_un address;    socklen_t len;    if (path_.length() > sizeof(address.sun_path)) {      int errno_copy = errno;      GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy);      throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path too long");    }    address.sun_family = AF_UNIX;    snprintf(address.sun_path, sizeof(address.sun_path), "%s", path_.c_str());    len = sizeof(address);    do {      if (0 == bind(serverSocket_, (struct sockaddr *) &address, len)) {        break;      }      // use short circuit evaluation here to only sleep if we need to    } while ((retries++ < retryLimit_) && (sleep(retryDelay_) == 0));  } else {    do {      if (0 == bind(serverSocket_, res->ai_addr, res->ai_addrlen)) {        break;      }      // use short circuit evaluation here to only sleep if we need to    } while ((retries++ < retryLimit_) && (sleep(retryDelay_) == 0));    // free addrinfo    freeaddrinfo(res0);#else      GlobalOutput.perror("TSocket::open() Unix Domain socket path not supported on windows", -99);      throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported");#endif  }  // throw an error if we failed to bind properly  if (retries > retryLimit_) {    char errbuf[1024];    if (! path_.empty()) {      sprintf(errbuf, "TServerSocket::listen() PATH %s", path_.c_str());    }    else {      sprintf(errbuf, "TServerSocket::listen() BIND %d", port_);    }    GlobalOutput(errbuf);    close();    throw TTransportException(TTransportException::NOT_OPEN, "Could not bind");  }#ifdef _WIN32  struct sockaddr_in addr;  socklen_t len = sizeof(addr);  addr.sin_family = AF_INET;  addr.sin_port = htons(port_);  addr.sin_addr.S_un.S_addr = INADDR_ANY;  if (0 != ::bind(serverSocket_, (struct sockaddr *)&addr, len))  {      int errno_copy = errno;      GlobalOutput.perror("TServerSocket::listen() bind() ", errno_copy);  }#endif  // Call listen  if (-1 == ::listen(serverSocket_, acceptBacklog_)) {    int errno_copy = errno;    GlobalOutput.perror("TServerSocket::listen() listen() ", errno_copy);    close();    throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy);  }  // The socket is now listening!}


原创粉丝点击