はじめましてC8H18です。
MFCのCSocketでTCP/IPによるサーバを作っています。
通常接続はCreate->Listen->OnAccept(クライアントからの接続要求)->Acceptの流れですが、
OnAcceptの時点でクライアントからの接続を拒否したいです。
Acceptを呼ばなければ良いわけでもないようで、
検索でも明確な答えを見つけられませんでした。
方法を知っている方意見、サイト等教えていただけないでしょうか?
よろしくお願いします。
Acceptしたのに拒否させるナンセンスな方法はやったことありません
が、Shutdownさせればどうなりますか?
因みに拒否したい場合、Listenしているソケット閉じたらダメなんで
すか?
以上。
> Acceptしたのに拒否させるナンセンスな方法はやったことありません
OnAccept が呼ばれた時点ならまだ Accept してないのでは。
> Listenしているソケット閉じたらダメなんですか?
当事者ではありませんが、俺なら、複数のクライアントからの接続を受け入れるサーバの場合、他のクライアントが接続してくるかもしれないのに、一時的とはいえ Listen ソケットを閉じるのには抵抗があります。
さて、接続拒否ですが、TCP/IP のレベルで行わなければなりませんか?
OnAccept の時点では、相手の IP アドレスもわかりません。
クライアントに接続を拒否された理由を通知したいような場合、一旦 Accept して、エラーメッセージを送って即切断、という手もあるかと思います。
ネットワークプロトコルは何層にもなっているものです。
今回も、TCP/IP の上に、C8H18 さんが使っているアプリケーション プロトコルがあるはずです。
TCP/IP レベルでは繋げておいて、アプリケーション プロトコル レベルでは拒否するというのはどうでしょうか。
> 今回も、TCP/IP の上に、C8H18 さんが使っているアプリケーション プロトコルがあるはずです。
> TCP/IP レベルでは繋げておいて、アプリケーション プロトコル レベルでは拒否するというのはどうでしょうか。
私もこの意見に賛成ですね。
アプリケーションレベルで情報のやり取りをする為のプロトコルを決めていると思うので
このレベルで何らかのエラー応答をして切断するのが良いと思います。
そうしないとLANケーブルが抜けたとかハード的なエラーと区別がつきませんし。
オショウさん、シャノンさん、PATIOさん、
色々な意見をありがとうございました。
オショウさんの言うように一時的にshutdownしようかと考えてましたが、
http://msdn.microsoft.com/ja-jp/library/3ebyk84x(VS.80).aspx
に、shutdown後再び使用してはいけないと書かれていました。
それにシャノンさんの言うようにAcceptするまで相手の情報がわからないのを忘れていました。
結局ご指摘の通り以下のようなコードで接続数で制限ができました。
ただShutDownがなくても自動的に切断されました。(自動変数だったためかと)
std::set<CAsyncSocket*> Connects;
void CSever::OnAccept(int nErrorCode)
{
CSocket::OnAccept(nErrorCode);
if (Connects.size() < 2) {
CAsyncSocket* sock = new CAsyncSocket();
Connects.insert(sock);
CAsyncSocket::Accept(*sock);
} else {
CAsyncSocket sock;
CAsyncSocket::Accept(sock);
sock.ShutDown(both);
}
}
やはりサーバはクライアントからのconnectはつないでみてから判断するものなのですね。
ツイート | ![]() |