簡単なポートフォワードのプログラムを作ろうと思って、
下のようなプログラムを組んでみました。

struct sockaddr_in cli ;

fd = SetupForClient(元IP, proto, port) ;
で、クライアントから接続を待って

clen = sizeof(cli) ;
recvfrom(fd, recv_data, sizeof(recv_data), 0,(struct sockaddr *)&cli, &clen) ;
でデータを受信して

fd2 = ConnectToServer(先IP, proto, port) ;
write(fd2, recv_data, sizeof(recv_data)) ;
で反対側のNICにデータを書き出す・・・。

という基本的なものなのですが、書き出す側に接続しようとすると
Connectの関数内で Address already in use というエラーが出てしまいます・・・。
fdを解放していないのかとも思ったのですが、再起動してもダメでした。

どういうことなのでしょうか・・・?

A 回答 (1件)

どうも不思議なんですが…。



これって1つのプログラムですよね。

最初にSetupForClient()で接続待ちをして、fdでデータを受け取る。

次に、どこかで接続待ちをしているサーバにConnectToServer()内で
接続をして、fd2で書き出す。

という手順だと理解したんですがいいですか?

だとすると、ConnectToServer()内で"Address already in use"に
なるというのが非常に不思議です。

"Address already in use"はbind()を実行してるところで
出てると思うんですが、何でクライアント側(ConnectToServer()
内ではこのプログラムはクライアントとして他のサーバへの
接続を試みている)でbind()を実行する必要があるんでしょう?

クライアント側では、socket() -> connect() という流れで
いいんじゃなかったでしたっけ?記憶違いかと思って手元の
ソースを見てるんですが、そうなってます。

ですから、ConnectToServer()の中に、connect()システムコールがあって、
bind()システムコールもあるようなら、bind()は取っ払ってください。

もし、私の解釈が違ってて、ConnectToServer()内でも
SetupForClient()と同様、サーバとして接続待ちをしているんなら、

  1.接続待ちポートをSetupForClient()と違うものに変える

  どうしても同じポートを使いたいなら、

  2.エラーが出なくなるまで待つ(ちゃんとclose()を
    コールしてポートを閉じても、全てのデータが完全に
    送受信されるように、同じポートがしばらく開けなく
    なることがあります)
  3.多分、SetupForClient()の中で、listen()、accept()の
    引数として渡した待ち受け用ソケットを、SetupForClient()
    の中で閉じてるかと思いますが、それを閉じずに使い回す。
    通常、同じポートで連続して複数の接続を受け付けるには、
    そのようにします。(普通は受け付け後さらにfork()します)

参考URL:http://www.kt.rim.or.jp/~ksk/sock-faq/unix-socke …

この回答への補足

ありがとうございます。ソースが学校にあっていま確認できないのですが、よく考えるとクライアントでbindするはずないですよね・・・。
プログラムの動きは、お察しの通り、クライアントAのデータを受け取ってサーバBに転送するものです。
(マスカレードでも良いんですが、認証を組み込んでみたいので)

だとすると、サーバとしてSetupForClient内でbindしようとしてコケている、ということになりますか・・・。
ただ、Linuxを起動したてでまっさらの状態でもAlready in useが出てしまうんです。
とりあえず、月曜にポートを変えてもう一度やってみようと思います。

補足日時:2001/06/29 23:45
    • good
    • 0
この回答へのお礼

ありがとうございました。ポートを変更して無事に動くようになりました。もう少し勉強してみます。

お礼日時:2001/07/03 18:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード


人気Q&Aランキング

おすすめ情報