[#38080] ポートが閉じているときの例外など — Mitsuru Ogino <ogino@...>

荻野と申します。いつも質問や要望ばかりですみません。

36 messages 2003/08/11
[#38086] Re: ポートが閉じているときの例外など — nobu.nakada@... 2003/08/12

なかだです。

[#38088] Re: ポートが閉じているときの例外など — IWAOKA Masahiro <iwaoka@...> 2003/08/12

いわおかです。

[#38091] Re: ポートが閉じているときの例外など — Mitsuru Ogino <ogino@...> 2003/08/12

荻野です。

[#38092] Re: ポートが閉じているときの例外など — nobu.nakada@... 2003/08/12

なかだです。

[#38093] Re: ポートが閉じているときの例外など — IWAOKA Masahiro <iwaoka@...> 2003/08/12

いわおかです。

[#38095] Re: ポートが閉じているときの例外など — Takahiro Kambe <taca@...> 2003/08/12

In message <20030812150516.GV37221@barber.fe.rn.tuat.ac.jp>

[#38102] Re: ポートが閉じているときの例外など — Tetsuo NAKAGAWA <tet@...> 2003/08/14

中川と申します。

[#38121] Re: ポートが閉じているときの例外など — Takahiro Kambe <taca@...> 2003/08/15

In message <20030814.140757.707824131.tetsuo@sapphire.siz.nes.nec.co.jp>

[#38123] Re: ポートが閉じているときの例外など — nobu.nakada@... 2003/08/16

なかだです。

[#38130] Re: ポートが閉じているときの例外など — Takahiro Kambe <taca@...> 2003/08/16

In message <200308160517.h7G5HcPL012839@sharui.nakada.kanuma.tochigi.jp>

[#38137] Re: ポートが閉じているときの例外など — nobu.nakada@... 2003/08/18

なかだです。

[#38139] Re: ポートが閉じているときの例外など — Takahiro Kambe <taca@...> 2003/08/18

In message <200308180959.h7I9xnb7001977@sharui.nakada.kanuma.tochigi.jp>

[#38122] ruby-tcpwrap and mkmf.rb — Takahiro Kambe <taca@...>

こんにちは。

16 messages 2003/08/16
[#38125] Re: ruby-tcpwrap and mkmf.rb — "Akinori MUSHA" <knu@...> 2003/08/16

At Sat, 16 Aug 2003 12:51:55 +0900,

[#38183] String << の動作につきまして — kuto@...

うと と申します。

44 messages 2003/08/22
[#38187] Re: String << の動作につきまして — Take_tk <ggb03124@...> 2003/08/22

たけ(tk)です。

[#38189] Re: String << の動作につきまして — Tadayoshi Funaba <tadf@...5.so-net.ne.jp> 2003/08/23

ふなばです。

[#38190] Re: String << の動作につきまして — Take_tk <ggb03124@...> 2003/08/23

たけ(tk)です。

[#38191] Re: String << の動作につきまして — Tadayoshi Funaba <tadf@...5.so-net.ne.jp> 2003/08/23

ふなばです。

[#38194] Re: String << の動作につきまして — Take_tk <ggb03124@...> 2003/08/23

たけ(tk)です。

[#38196] Re: String << の動作につきまして — Tadayoshi Funaba <tadf@...5.so-net.ne.jp> 2003/08/23

ふなばです。

[#38203] Re: String << の動作につきまして — 西 啓一朗 <receiver@...> 2003/08/23

ども、西啓一朗@Ktouth Brand. です。

[#38208] Re: String << の動作につきまして — Tadayoshi Funaba <tadf@...5.so-net.ne.jp> 2003/08/23

ふなばです。

[#38211] Re: String << の動作につきまして — 西 啓一朗 <receiver@...> 2003/08/24

ども、西啓一朗@Ktouth Brand. です。

[#38195] 理解の進め方(Re: String << の動作につきまして) — Tadashi Oh-Ya <toy@...>

おおやです。

36 messages 2003/08/23
[#38206] 理解の進め方:シュールな世界 — Take_tk <ggb03124@...> 2003/08/23

たけ(tk)です。

[#38233] シュールな名前 — Take_tk <ggb03124@...> 2003/08/25

たけ(tk)です

[#38198] Tmailで送るメールに日付がつけられなくなりました — 川田誠司 <kawada.seiji@...>

はじめまして

11 messages 2003/08/23

[#38256] かみ砕いた説明をすべき範囲 — 西 啓一朗 <receiver@...>

ども。西啓一朗@Ktouth Brand. です。

41 messages 2003/08/26
[#38258] Re: かみ砕いた説明をすべき範囲 — nobu.nakada@... 2003/08/26

なかだです。

[#38261] Re: かみ砕いた説明をすべき範囲 — Take_tk <ggb03124@...> 2003/08/26

たけ(tk)です

[#38262] Re: かみ砕いた説明をすべき範囲 — nobu.nakada@... 2003/08/26

なかだです。

[#38264] Re: かみ砕いた説明をすべき範囲 — Take_tk <ggb03124@...> 2003/08/26

たけ(tk)です

[#38265] Re: かみ砕いた説明をすべき範囲 — IWAOKA Masahiro <iwaoka@...> 2003/08/26

いわおかです。

[#38267] Re: かみ砕いた説明をすべき範囲 — Take_tk <ggb03124@...> 2003/08/26

たけ(tk)です

[#38273] Re: かみ砕いた説明をすべき範囲 — matz@... (Yukihiro Matsumoto) 2003/08/26

まつもと ゆきひろです

[ruby-list:38139] Re: ポートが閉じているときの例外など

From: Takahiro Kambe <taca@...>
Date: 2003-08-18 16:44:54 UTC
List: ruby-list #38139
In message <200308180959.h7I9xnb7001977@sharui.nakada.kanuma.tochigi.jp>
	on Mon, 18 Aug 2003 18:59:50 +0900,
	nobu.nakada@nifty.ne.jp wrote:
> > (必須ではないかもしれませんが)EINPRROGRESSのときもやった方が良いと言え
> > ます。早くエラーが検知できて、connect(2)の呼び出しを1回節約できる場合
> > があります。
> 
> EINPROGRESSのような時間がかかっているときに、システムコール一回
> の間くらいではそうそう条件は変わらないのではないかという気がす
> るのですが。
手元のテストでは、

1. connect()失敗 (EINPROGRESS)
2. getsockopt()で ECONNREFUSED を検知

といったことが確認できています。相手がlocalhostだと、同一ホスト内なの
でEINPROGRESSに至る間もなく、ECONNREFUSEDであることがわかります。同一
LAN上のホストを相手にすると、EINPROGRESSの場合にgetsockopt(2)でチェッ
クしない場合は、

1. connect()失敗 (EINPROGRESS)
2. connect()失敗 (EINVAL)
3. getsockopt()で ECONNREFUSED を検知

となります。

CPUが高速、メモリやハードディスクがいっぱいになっても、システムコール
にかかるオーバーヘッドは、(システムコールの呼び出しを伴わない)ライブラ
リに比べるとはるかに大きいものです。必要のないシステムコールの呼び出し
をやめることができることができれば、それに越したことはありません。

> 対応としては、FreeBSD(*BSD全部?)でもWAIT_IN_PROGRESSを有効にす
> るということでいいんでしょうか。全システムで有効にしたほうがい
> いのかな?
以下の環境の確認はできました。

	NetBSD 1.6 and current
	FreeBSD 2.2.8
	OpenBSD 3.3

FreeBSDの最新のものはチェックできません。

	http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=22522

に含めたテストプログラムを後ろに付けます。PR(Problem Report)にも書きま
したが、connect(2)でEINVALになる場合は、

	% cc test.c
	% ./a.out 192.168.32.10 12345
	connect to family = 2, port = 234, addr = 192.168.32.10
	connect: Operation now in progress
	getsockopt => Connection refused
	connect to family = 2, port = 234, addr = 192.168.32.10
	connect: Invalid argument
	getsockopt => 0

となります。

=====================================================================

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

static int connect_test(int, struct sockaddr_in *, int, int);

#define GETSOCKOPT_AFTER_EINPROGRESS	1
#define GETSOCKOPT_AFTER_EINVAL		1

static int exit_after_getsockopt = 0;

int
main(int argc, char **argv)
{
	char *host, *port;
	struct hostent *ht;
	unsigned short p;
	int fd, status, n;
	struct sockaddr_in sin;

	if (argc == 3) {
		host = argv[1];
		port = argv[2];
	} else {
		fputs("Need host and port as parameter.\n", stderr);
		exit(1);
	}
	n = atoi(port);
	if (n <= 0 || n > 65535) {
		fputs("Invalid port number.\n", stderr);
		exit(1);
	}
	p = n;

	ht = gethostbyname(host);
	if (ht == NULL) {
		herror(host);
	}
	memset(&sin, '\0', sizeof sin);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(p);
	memcpy(&sin.sin_addr, ht->h_addr_list[0], ht->h_length);

	fd = socket(PF_INET, SOCK_STREAM, 0);
	status = connect_test(fd, &sin, sizeof sin, 0);
	return(status);
}

static int
connect_test(fd, sockaddr, len, socks)
    int fd;
    struct sockaddr_in *sockaddr;
    int len;
    int socks;
{
    int status;
    int mode;
#if (GETSOCKOPT_AFTER_EINPROGRESS == 1) || (GETSOCKOPT_AFTER_EINVAL == 1)
    int value;
#endif

    mode = fcntl(fd, F_GETFL, 0);

    fcntl(fd, F_SETFL, mode | O_NONBLOCK);

    for (;;) {
	printf("connect to family = %d, port = %d, addr = %s\n",
	       sockaddr->sin_family, ntohs(sockaddr->sin_port),
	       inet_ntoa(sockaddr->sin_addr));

	status = connect(fd, (struct sockaddr *)sockaddr, len);
	if (status < 0) {
		perror("connect");
		switch (errno) {
		case EAGAIN:
		case EINPROGRESS:
#if (GETSOCKOPT_AFTER_EINPROGRESS == 1)
			len = sizeof(value);
			getsockopt(fd, SOL_SOCKET, SO_ERROR, &value, &len);
			printf("getsockopt => %s\n",
				(value != 0) ? strerror(value): "0");
			if (exit_after_getsockopt)
				goto error;
#endif
			continue;
		case EISCONN:
			status = 0;
			break;
		case EINVAL:
#if (GETSOCKOPT_AFTER_EINVAL == 1)
			len = sizeof(value);
			getsockopt(fd, SOL_SOCKET, SO_ERROR, &value, &len);
			printf("getsockopt => %s\n",
				(value != 0) ? strerror(value): "0");
			if (exit_after_getsockopt)
				goto error;
#endif
			break;
		default:
			break;
		}
	}
#if (GETSOCKOPT_AFTER_EINPROGRESS == 1) || (GETSOCKOPT_AFTER_EINVAL == 1)
    error: ;
#endif
	fcntl(fd, F_SETFL, mode);
	return status;
    }
}

=====================================================================

-- 
神戸 隆博 / Takahiro Kambe


In This Thread