From: Kikutani Makoto Date: 1997-09-17T19:15:25+09:00 Subject: [ruby-list:4378] Re: socket きくたにです。 Wed, Sep 17, 1997 at 06:01:14PM +0900 において Shoichi OZAWA さん曰く: > 休憩時間にちょっと考えてみました。ソケットはよく知らない > のですが、そのまま ruby になおしてみました。こんなんでどうでしょう? ありがとうございます。でも、なんだか動かないようです... > でも、ipc0.rb はどうやって反対側のソケットを使うのでしょうか? > # ソケット知らないのがバレバレ。 いやあ、私も全然知らないのですが、参考にしているプログラムを 見てると、子プロセスとして起動されるものは同じチャネルで 入出力両方に使っているようです。 さっきの変更版: ------------------------------------------------------------ #include #include #include #include main() { int pid, i, slen, l; char *cmd, *arg0, arg1[8], *str; int channel[2]; /* IPC channel with child process */ char buf[10]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, channel) < 0) { fprintf(stderr, "socketpair failed\n"); return; } if ((pid = vfork()) == -1) { return; } if (pid == 0) { /* child process */ #if 1 cmd = "./ipc0"; arg0 = "ipc0"; #else cmd = "./ipc0.rb"; arg0 = "ipc0.rb"; #endif sprintf(arg1, "%d", channel[0]); execl(cmd, arg0, arg1, NULL); perror("execl failed"); close( channel[0] ); _exit( 1 ); } /* parent process */ close(channel[0]); i = 0x12345678; if ((l = write( channel[1], &i, sizeof(int))) != sizeof(int)) printf("ipc-test0.c: int write failed. written length = %d\n", l); if ((l = read( channel[1], buf, 3)) != 3) /* 状態を読むように変更 */ printf("ipc-test0.c: int read failed. read length = %d\n", l); printf("buf = %s\n", buf); str = "ruby"; slen = strlen(str)+1; if ((l = write( channel[1], str, slen)) != slen) printf("ipc-test0.c: str write failed. written length = %d\n", l); if ((l = read( channel[1], buf, 3)) != 3) printf("ipc-test0.c: int read failed. read length = %d\n", l); printf("buf = %s\n", buf); } ------------------------------------------------------------ ipc0.c ------------------------------------------------------------ #include main(int argc, char *argv[]) { char buf[10]; int l, i; int channel = atoi(argv[1]); if ((l = read( channel, buf, 4)) != 4) printf("int read failed. read length = %d\n", l); for (i = 0; i < 4; ++i) printf("ipc0.c: int byte = %x\n", buf[i]); if ((l = write( channel, "OK", 3)) != 3) printf("ipc0.c: int write failed. written length = %d\n", l); if ((l = read( channel, buf, 5)) != 5) printf("str read failed. read length = %d\n", l); printf("ipc0.c: str = %s\n", buf); if ((l = write( channel, "OK", 3)) != 3) printf("ipc0.c: str write failed. written length = %d\n", l); } ------------------------------------------------------------ で、この上のをrubyで書いて ------------------------------------------------------------ #!/usr/bin/ruby channel = ARGV.shift printf "ipc0.rb: channel = %d\n", channel inport = IO.new(channel, "r") outport = IO.new(channel, "w") i = inport.read(4) i.each_byte {|byte| printf "ipc0.rb: int byte = %x\n", byte } outport.write("OK") s = inport.read(5) outport.write("OK") printf "ipc0.rb: str = %c\n", s ------------------------------------------------------------ なんてするのはダメなようで、ちょっとCでのソケットと挙動が 違うのが小澤さんの例では動かない原因かもしれません。 # Unixプログラミングを知らん者がソケットなんか使うなという説も -- 人生を背負い投げ 菊谷 誠(Kikutani Makoto) kikutani@eis.or.jp kikutani@jdc.ericsson.se hgf03701@niftyserve.or.jp http://www.eis.or.jp/muse/kikutani/