通信
- サーバーソケット
サーバーソケットクラス実装例を示します。
まずはSocketStateObjectというクラスを作成し、このインスタンスを使ってデータの入出力を行います。
public class SocketStateObject
{
public Socket ConnectedSocket = null;// Connectedソケット
public byte[] Data;// 受信バッファ
public SocketStateObject()
{
Data = new byte[ 256 ];
}
/// <summary>リモートポート</summary>
public int RemotePortNo
{
get
{
if( ConnectedSocket.Connected == false ) return 0;
return ( ( IPEndPoint )ConnectedSocket.RemoteEndPoint ).Port;
}
}
}
次にサーバーソケットを作成します。
/// <summary>非同期サーバーソケットクラス</summary>
public class SocketServer
{
// リスナーソケット
private Socket _listenerSocket = null;
// 通信ソケット(マルチクライアント対応)
private List<Socket> _ltConnectedSockets;
public SocketServer()
{
_ltConnectedSockets = new List<Socket>();
}
/// <summary>リッスン開始</summary>
/// <param name="nLocalPortNo">リッスンポート</param>
public void Listen( int nLocalPortNo )
{
IPEndPoint lepRemote = new IPEndPoint( IPAddress.Any, nLocalPortNo );
// リスナーソケット作成
_listenerSocket = new Socket( lepRemote.Address.AddressFamily
, SocketType.Stream, ProtocolType.Tcp );
// リッスン開始
_listenerSocket.Bind( lepRemote );
_listenerSocket.Listen( 10 );
// 接続待ち
_listenerSocket.BeginAccept( new AsyncCallback( this.AcceptCallback ), _listenerSocket );
}
/// <summary>アクセプトイベント処理</summary>
/// <param name="ar">ソケットオブジェクト</param>
private void AcceptCallback( IAsyncResult ar )
{
if( _listenerSocket == null ) return;
// 次のクライアントのためにAccept開始
_listenerSocket.BeginAccept( new AsyncCallback( this.AcceptCallback ), _listenerSocket );
// ステートオブジェクト作成
SocketStateObject stateObject = new SocketStateObject();
Socket sockListener = ( Socket )ar.AsyncState;
stateObject.ConnectedSocket = sockListener.EndAccept( ar );
_ltConnectedSockets.Add( stateObject.ConnectedSocket );
// 受信開始
stateObject.ConnectedSocket.BeginReceive( stateObject.Data, 0
, stateObject.Data.Length, SocketFlags.None
, new AsyncCallback( this.ReceiveCallback ), stateObject );
}
/// <summary>受信完了コールバック</summary>
/// <param name="ar">ソケットオブジェクト</param>
private void ReceiveCallback( IAsyncResult ar )
{
SocketStateObject stateObject = ( SocketStateObject )ar.AsyncState;
// 受信完了
int nReceivedLength = stateObject.ConnectedSocket.EndReceive( ar );
// 受信データ
byte[] receivedData = new byte[nReceivedLength];
Array.Copy( stateObject.Data, receivedData, nReceivedLength );
// 次受信開始
stateObject.ConnectedSocket.BeginReceive( stateObject.Data, 0
, stateObject.Data.Length, SocketFlags.None
, new AsyncCallback( this.ReceiveCallback ), stateObject );
}
/// <summary>バイナリメッセージ送信開始</summary>
/// <param name="btData">バイナリメッセージ</param>
public void Send( byte[] btData )
{
if( _ltConnectedSockets.Count <= 0 ) return;
// ここではとりあえず先頭のクライアント。
Socket socket = _ltConnectedSockets[ 0 ];
if( socket == null ) return;
// 送信開始
socket.BeginSend( btData, 0, btData.Length, SocketFlags.None,
new AsyncCallback( SendCallback ), socket );
// マルチクライアントの時、指定のリモートポート番号で検索して
// そのインスタンスを使って送信すればよい。
}
/// <summary>送信完了コールバック</summary>
/// <param name="ar">ソケットオブジェクト</param>
private void SendCallback( IAsyncResult ar )
{
Socket sockConnected = ( Socket )ar.AsyncState;
// 送信完了
int nSent = sockConnected.EndSend( ar );
}
}