Commit fe697725 authored by Hisashi Horikawa's avatar Hisashi Horikawa
Browse files

bit.

parent fb74eeb6
......@@ -20,6 +20,8 @@
#include <sys/socket.h>
#include <unistd.h>
typedef int SOCKET;
#define INVALID_SOCKET -1
#define closesocket close
#endif // _WIN32
#include <assert.h>
#include <errno.h>
......@@ -39,6 +41,7 @@ static Synchronize cs;
* gethostbyname() is obsolete.
*
* @param hostname ホスト名. nullptr のときは, loopbackアドレス.
* @param port ポート番号. 1以上.
* @param socktype TCP なら SOCK_STREAM
* @return エラーの場合, NULL. TODO: エラーが発生したとき例外を投げるか?
*
......@@ -170,7 +173,7 @@ InterruptedIOException::~InterruptedIOException() noexcept
////////////////////////////////////////////////////////////////////////
// CSocket
CSocket::CSocket(): sock_fd(-1)
CSocket::CSocket(): sock_fd(INVALID_SOCKET)
{
}
......@@ -180,29 +183,20 @@ CSocket::~CSocket()
}
static int close_socket(SOCKET sock)
{
#ifdef _WIN32
return closesocket(sock);
#else
return close(sock);
#endif
}
#define BACKLOG 5
/**
* TCP で listen する.
* TCP で listen する. IPv6対応
*
* @param node bind() するホスト名. NULL の場合, INADDR_ANY, IN6ADDR_ANY_INIT.
* @param port ポート番号. 0 の場合, ephemeral port のなかで, 空いているポート
* を割り当てる.
*
* @return 正常な場合, 新しい CSocket インスタンス
* @return 正常な場合, 新しい CSocket インスタンス.
* エラーの場合, NULL か, 例外 SystemCallError
*/
CSocket* CSocket::setupServer(const char* node, int port) noexcept(false)
{
// (node, service) の両方を nullptr にすると, getaddrinfo() が失敗するが,
// このようにすれば, ephemeral port から取れる.
if ( port < 0 )
return nullptr;
......@@ -216,19 +210,17 @@ CSocket* CSocket::setupServer(const char* node, int port) noexcept(false)
// AI_PASSIVE をセットせずに, node = NULL の場合は, loopbackアドレス
// (INADDR_LOOPBACK or IN6ADDR_LOOPBACK_INIT).
// => connect(2), sendto(2), or sendmsg(2) 用.
// AI_PASSIVE をセットして, node = NULLのとき, INADDR_ANY, IN6ADDR_ANY_INIT.
// => bind(2) 用.
// AI_PASSIVE をセットして, node = NULLのときは, INADDR_ANY, IN6ADDR_ANY_INIT.
#ifdef _WIN32
hints.ai_flags = AI_PASSIVE;
#else
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
#endif
// (node, service) の両方を nullptr にすると getaddrinfo() が失敗するが,
// このようにすれば, ephemeral port から取れる.
char service[11];
sprintf(service, "%d", port);
int err = getaddrinfo(node, service, &hints, &res);
if (err != 0) {
fprintf(stderr, "getaddrinfo() failed: %s\n", gai_strerror(err));
......@@ -237,7 +229,7 @@ CSocket* CSocket::setupServer(const char* node, int port) noexcept(false)
//struct addrinfo* ai = res;
SOCKET sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd < 0) {
if ( sockfd == INVALID_SOCKET ) {
int e = errno;
//perror("socket open failed");
freeaddrinfo(res);
......@@ -247,7 +239,7 @@ CSocket* CSocket::setupServer(const char* node, int port) noexcept(false)
int reuse = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse,
sizeof(reuse)) < 0) {
close_socket(sockfd);
closesocket(sockfd);
freeaddrinfo(res);
return nullptr;
}
......@@ -256,7 +248,8 @@ CSocket* CSocket::setupServer(const char* node, int port) noexcept(false)
if (bind(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
int e = errno;
//perror("bind() failed");
close_socket(sockfd);
closesocket(sockfd);
freeaddrinfo(res);
throw SystemCallError(e, "bind() failed");
}
......@@ -264,10 +257,10 @@ CSocket* CSocket::setupServer(const char* node, int port) noexcept(false)
freeaddrinfo(res);
res = nullptr;
if (listen(sockfd, 5) < 0) { // 5 is magic
if (listen(sockfd, BACKLOG) < 0) { // 5 is magic
int e = errno;
//perror("listen() failed");
close_socket(sockfd);
closesocket(sockfd);
throw SystemCallError(e, "listen() failed");
}
......@@ -275,13 +268,13 @@ CSocket* CSocket::setupServer(const char* node, int port) noexcept(false)
CSocket* result = new CSocket();
result->sock_fd = sockfd;
// ephemeral port の場合があるので, 取得しなおす.
// 自分のポート番号を得るために, いつでも取得しなおす.
result->addrlen = sizeof(result->addr);
memset(&result->addr, 0, result->addrlen);
if (getsockname(sockfd, (sockaddr*) &result->addr, &result->addrlen) < 0) {
int e = errno;
//perror("getsockname() failed");
close_socket(sockfd);
closesocket(sockfd);
delete result;
throw SystemCallError(e, "getsockname() failed");
}
......
......@@ -3,14 +3,12 @@
#ifndef PTR_VECTOR_H__
#define PTR_VECTOR_H__ 1
#include <vector>
#include <type_traits>
#ifndef NDEBUG
#include <stdio.h>
#endif
/**
* 使い方:
* ptr_vector<Foo*> var;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment