したがって、私のソフトウェアでは、ネットワーク上でディスカバー ブロードキャストを送信すると、そのブロードキャストを受信するすべての「クライアント」が TCP 経由で接続されます。私が持っているものでは、「OK」に機能しているように見えますが、もっと良い方法が必要だと感じています. 私が見ているのは、現在別のソケットの受け入れに取り組んでいるため、ソフトウェアへの一部の TCP 接続が拒否されていることです (と思います)。したがって、現在のバージョンでは、約 80% の確率でソケットを受け入れることができます。それ以上の場合もありますが、通常は 80% 前後です。残りは私のソフトウェアによって拒否され、その理由はわかりません。私にはそれは受け入れられませんが、この数値を改善することはできません。
これは、TCP クライアントを受け入れ、接続された新しいソケットについて他のクラスに通知するために使用するクラスです。
public class AsynchronousSocketListener
{
// Thread signal.
public ManualResetEvent allDone = new ManualResetEvent(false);
public event EventHandler<ErtdRawDataArgs> ClientConnected;
private string bindingIp;
public string AddressBind
{
get { return this.bindingIp; }
private set { this.bindingIp = value; }
}
private int port;
public int Port
{
get { return this.port; }
private set { this.port = value; }
}
private Socket listener;
public AsynchronousSocketListener(string bindingIp, int port)
{
this.bindingIp = bindingIp;
this.port = port;
}
protected void OnClientConnected(string data, IPEndPoint clientEP)
{
if (this.ClientConnected == null)
return;
Task.Factory.StartNew(() =>
{
//build args
ErtdRawDataArgs args = new ErtdRawDataArgs(Encoding.Default.GetBytes(data));
args.Source = string.Format("{0}:{1}", clientEP.Address.ToString(), clientEP.Port);
this.ClientConnected(this, args);
});
}
public void Close()
{
if (this.listener == null || !this.listener.Connected)
return;
this.listener.Shutdown(SocketShutdown.Both);
this.listener.Close();
}
public void StartListening()
{
Task.Factory.StartNew(() =>
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(this.bindingIp), this.port);
// Create a TCP/IP socket.
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
int maxConnections = (int)SocketOptionName.MaxConnections;
listener.Listen(maxConnections);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
});
}
public void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0) {
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
OnClientConnected(content, handler.RemoteEndPoint as IPEndPoint);
//close socket
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
}
このコードを改善する方法はありますか、またはほぼ同時に TCP 接続を受け入れる結果を改善するために、まったく異なるものがありますか?