次のサンプル プログラムは、単純なソケット通信を実装し、複数のクライアントを開くことができます。ローカルテストは合格しましたが、オンラインテストは行われませんでした。
サーバー:
System.Net を使用、
System.Net.Sockets を使用、
System.Collections を使用
。
namespace MySocketServer1
{
public Partial class Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");//このマシンをテストに使用します
private IPEndPoint serverFullAddr;//完全な端末アドレス
private
Socket sock;
Timer myTimer
; //複数の接続が確立されている場合に接続を保存するために使用されます。
public Form1()
{
InitializeComponent()
}
private void btStart_Click(object sender, EventArgs e)
{
serverFullAddr = new IPEndPoint(serverIP, 1000); //ポート番号 1000 を取得します。
//Socket オブジェクトを構築します。ソケット タイプは「ストリーム ソケット」で、5 つのタプルを指定します。プロトコル要素
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//
5 つのタプルでローカル バイナリ、つまりローカル ホスト アドレスとポート番号を指定します。
sock.Bind(serverFullAddr);
/Listen 受信接続の有無にかかわらず、保留中の接続キューの最大値を 20 に指定します。
sock.Listen(20);
alSock = 新しい ArrayList();
//時間ギャップが 1 秒のタイマーを構築します。つまり、accept() メソッドを毎秒実行して、接続要求キュー内の最初の保留中の接続要求を取得します。
myTimer =new System.Timers.Timer(1000 )
;経過 +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed
)
;
private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
myTimer.Enabled = false;
//accept() を実行すると、一時停止キューが空になるとこのスレッドがブロックされ、前のステートメントによりタイマーが停止します。 , until // 接続が
ソケットに渡されるまで acceptSock = sock.Accept();
// accept() によって生成された Socket オブジェクトを ArrayList に格納します
alSock.Add(acceptSock);
// Threading.Timer オブジェクトを構築します。これにより、プログラムは別のスレッドを開始します。スレッドはコールバック関数を実行し、デリゲート制限 //関数パラメータはオブジェクト型である必要があります。 Threading.Timer コンストラクターの 2 番目のパラメーターは、コールバック関数に渡されるパラメーターです。 // 3 番目のパラメーターは、コールバック関数を呼び出すまでの遅延を指定します。0 の場合、最後のパラメーターは呼び出し時間を指定します。コールバック関数 // Interval、0 に設定すると、1 回だけ実行されます。
System.Threading.Timer ti = new System.Threading.Timer(new
TimerCallback(ReceiveMsg)
,acceptSock
, 0, 0);
private void ReceiveMsg(object obj)
{
Socket acceptSock = (Socket)obj;
try
{
while (true)
{
byte[] byteArray = new byte[100];
//データを受信
//バイト変換配列を
文字列に変換します strRec = System.Text.Encoding.UTF8.GetString(byteArray);
if (this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(this.ChangeRickTextBox), new
object[] { strRec , EventArgs.Empty });
}
}
}
catch(Exception ex)
{
acceptSock.Close();
MessageBox.Show("S:受信メッセージ エラー"+ex.Message
)
;
private void ChangeRickTextBox(object obj,EventArgs e)
{
string s = System.Convert.ToString(obj);
this.rtbReceive.AppendText(s + Environment.NewLine)
;
private void btSend_Click(object sender, EventArgs e)
{
Socket sc=null;
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray());
//
にいくつかあります
。
同時に、クライアントが接続するときに、textBox1 に送信する接続を入力します。
int Index = int.Parse(this.textBox1.Text.Trim());
//
データを送信します
。 .Send(byteSend);
}
catch(Exception ex)
{
if(sc != null)
{
sc.Close()
}
MessageBox.Show("S: メッセージ送信エラー"+ex.Message
)
;
private void btClose_Click(object sender, EventArgs e)
{
try
{
Application.Exit();
}
catch (Exception ex)
{
MessageBox.Show
("S
:Close Socket Error" + ex.Message)
;
==
=
= == == == == == == == == == == == == == == == == == == == == == == == = = = = == == == ==
クライアント:
System.Net を使用;
System.Net.Sockets を使用
;
namespace MySocketClient1
{
public 部分クラス Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");
private IPEndPoint serverFullAddr
;
public Form1()
{
InitializeComponent()
}
private void btConnect_Click(object sender, EventArgs e)
{
try
{
serverFullAddr = new IPEndPoint(serverIP, 1000)
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//リモートホストへの接続を確立する
//データを受信するための新しいスレッドを開始します
Thread t = new Thread(new ThreadStart(ReceiveMsg));
t.Name = "Receive Message";
//スレッドはバックグラウンド スレッドまたはフォアグラウンド スレッドのいずれかです。バックグラウンド スレッドは、 // バックグラウンド スレッドがプロセスの終了を妨げないことを除いて、フォアグラウンド スレッドと似ています。プロセスに属するすべてのフォアグラウンド スレッドが終了すると、共通言語ランタイムは // まだアクティブなバックグラウンド スレッドで Abort を呼び出してプロセスを終了します。
t.IsBackground = true;
t.Start();
}
catch
(Exception ex)
{
MessageBox.Show(ex.Message)
}
private
void ReceiveMsg()
{
try
{
while (true)
{
byte[] byteRec = new byte[100]
;
string strRec = System.Text.Encoding.UTF8.GetString(byteRec);
(this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(ChangeRtb), new object[]
{ strRec, EventArgs.Empty })
}
}
}
catch(Exception ex)
{
MessageBox.Show("受信メッセージ エラー" "+ex.メッセージ);
}
}
private void ChangeRtb(object obj, EventArgs e)
{
string s = System.Convert.ToString(obj);
this.rtbReceive.AppendText(s + Environment.NewLine)
;
private void btSend_Click(object sender, EventArgs e)
{
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(
this.tbSend.Text.ToCharArray(
));
try
{
this.sock.Send(byteSend);
{
MessageBox.Show("メッセージ送信エラー")
}
}
private void btClose_Click(object sender, EventArgs e)
{
try
{
this.sock.Shutdown(SocketShutdown.Receive);
this.sock.Close()
}
catch
{
MessageBox.Show
("終了エラー"); ;
} }
}
}
パズル
:
クライアント側の赤いマークのステートメント: this.sock.Shutdown(SocketShutdown.Prevent
) または this.sock.Shutdown(SocketShutdown. Send);
その後、[閉じる] ボタンをクリックすると、CPU 使用率が 100% に急増します。ただし、this.sock.Shutdown(SocketShutdown.Receive); を使用する
か、Shutdown() メソッドを呼び出さない場合は、この問題は発生しません。クライアントはShutdown()を使用すべきではないでしょうか?
http://www.cnblogs.com/KissKnife/archive/2006/08/13/475707.html