โปรแกรมตัวอย่างต่อไปนี้ใช้การสื่อสารซ็อกเก็ตอย่างง่ายและสามารถเปิดไคลเอนต์ได้หลายตัว การทดสอบในพื้นที่ผ่าน แต่ไม่มีการทดสอบออนไลน์
เซิร์ฟเวอร์:
ใช้ System.Net;
ใช้ System.Net.Sockets;
ใช้
System.Threading;
namespace MySocketServer1
{
คลาสสาธารณะบางส่วน Form1 : ฟอร์ม
{
ส่วนตัว IPAddress serverIP = IPAddress.Parse("127.0.0.1");//ใช้เครื่องนี้สำหรับการทดสอบ
เซิร์ฟเวอร์ IPEndPoint ส่วนตัวFullAddr;//
ถุงเท้าซ็อกเก็ตส่วนตัว
ของเทอร์
มินัลแบบเต็ม;Timer myTimer;
private ArrayList alSock;//ใช้เพื่อบันทึกการเชื่อมต่อเมื่อมีการสร้างการเชื่อมต่อหลายรายการ
Form1 สาธารณะ ()
{
เตรียมใช้งานส่วนประกอบ ()
;
โมฆะส่วนตัว btStart_Click (ผู้ส่งวัตถุ EventArgs e)
{
serverFullAddr = new IPEndPoint (serverIP, 1000); // รับหมายเลขพอร์ต 1,000
// สร้างวัตถุซ็อกเก็ตประเภทซ็อกเก็ตคือ "สตรีมซ็อกเก็ต" ระบุห้า tuple
ถุงเท้าองค์ประกอบโปรโตคอล
= ซ็อกเก็ตใหม่ (AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//
ระบุไบนารีท้องถิ่นในห้า tuple นั่นคือที่อยู่โฮสต์ในเครื่องและหมายเลขพอร์ต
sock.Bind (serverFullAddr);
/Listen ไม่ว่าจะมีการเชื่อมต่อเข้ามาหรือไม่ ให้ระบุค่าสูงสุดของคิวการเชื่อมต่อที่รอดำเนินการเป็น 20
sock.Listen(20);
alSock = ArrayList ใหม่();
//สร้างตัวจับเวลาโดยมีช่องว่างเวลา 1 วินาที นั่นคือ ดำเนินการเมธอด Accept() ทุกวินาทีเพื่อรับคำขอการเชื่อมต่อที่ค้างอยู่ครั้งแรกในคิวคำขอการเชื่อมต่อ
myTimer =new System.Timers.Timer(1000 )
; ที่ผ่านไป + = System.Timers.EventHandler ใหม่ (myTimer_Elapsed);
myTimer.Enabled = true
;
โมฆะส่วนตัว myTimer_Elapsed (ผู้ส่งวัตถุ System.Timers.ElapsedEventArgs e)
{
myTimer.Enabled = false;
//Execute ยอมรับ () เธรดนี้จะถูกบล็อกเมื่อคิวการระงับว่างเปล่า และผู้จับเวลาจะหยุดเนื่องจากคำสั่งก่อนหน้า จนกระทั่ง // จนกว่าการเชื่อมต่อจะถูกส่งผ่านไปยัง
Socket AcceptSock = sock.Accept();
// จัดเก็บอ็อบเจ็กต์ Socket ที่สร้างโดย Accept() ลงใน ArrayList
alSock.Add(acceptSock);
// สร้างอ็อบเจ็กต์ Threading.Timer ซึ่งจะทำให้โปรแกรมสตาร์ทเธรดอื่น เธรดจะดำเนินการฟังก์ชันการโทรกลับ และพารามิเตอร์ขีดจำกัดการมอบหมาย // ฟังก์ชันต้องเป็นประเภทอ็อบเจ็กต์ พารามิเตอร์ตัวที่สองของตัวสร้าง Threading.Timer คือพารามิเตอร์ที่ส่งผ่านไปยังฟังก์ชันการโทรกลับ // พารามิเตอร์ตัวที่สามระบุความล่าช้าก่อนที่จะเรียกใช้ฟังก์ชันการโทรกลับ หากเป็น 0 พารามิเตอร์ตัวสุดท้ายจะระบุเวลาในการโทร ฟังก์ชั่นการโทรกลับ // Interval หากตั้งค่าเป็น 0 จะถูกดำเนินการเพียงครั้งเดียว
System.Threading.Timer ti = new System.Threading.Timer (TimerCallback ใหม่
(ReceiveMsg), AcceptSock, 0, 0);
myTimer.Enabled = true
;
ส่วนตัวรับเป็นโมฆะ (วัตถุ obj)
{
ซ็อกเก็ต AcceptSock=
(ซ็อกเก็ต) obj;
ลอง
{
ในขณะที่ (จริง)
{
ไบต์
[] byteArray = ไบต์ใหม่ [100];
อาร์เรย์เป็น
สตริง strRec = System.Text.Encoding.UTF8.GetString(byteArray);
if (this.rtbReceive.InvoidRequired)
{
this.rtbReceive.Invoid(new EventHandler(this.ChangeRickTextBox), new
object[] { strRec , EventArgs.Empty });
}
}
}
catch(ข้อยกเว้น เช่น)
{
AcceptSock.Close();
MessageBox.Show("S:Receive Message Error"+ex.Message
)
;
โมฆะส่วนตัว ChangeRickTextBox (วัตถุ obj, EventArgs e)
{
string s = System.Convert.ToString (obj);
this.rtbReceive.AppendText (s
+ Environment.NewLine)
โมฆะส่วนตัว btSend_Click (ผู้ส่งวัตถุ EventArgs e)
{
ซ็อกเก็ต sc = null;
ไบต์ [] byteSend =
System.Text.Encoding.UTF8.GetBytes (this.tbSend.Text.ToCharArray ());
ลอง
{
// มีหลายที่ ในเวลาเดียวกันเมื่อไคลเอนต์เชื่อมต่อให้ป้อนการเชื่อมต่อที่จะส่งใน textBox1
int index = int.Parse(this.textBox1.Text.Trim());
sc = (Socket)alSock[index - 1];
//Send data
sc .Send(byteSend);
}
catch(ข้อยกเว้น เช่น)
{
if(sc != null)
{
sc.Close();
}
MessageBox.Show("S:Send Message Error"+ex.Message
)
;
โมฆะส่วนตัว btClose_Click (ผู้ส่งวัตถุ EventArgs e)
{
ลอง
{
Application.Exit();
}
catch
(ข้อยกเว้น เช่น)
{
MessageBox.Show
("S:Close Socket Error" +
ex.Message
)
;
= == == == == == == == == == == == == == == == == == == == == == == == = = = = = == == == ==
ลูกค้า:
ใช้ System.Net;
ใช้
System.Net.Sockets;
namespace MySocketClient1
{
คลาสสาธารณะบางส่วน Form1 : แบบฟอร์ม
{
เซิร์ฟเวอร์ IPAddress ส่วนตัว = IPAddress.Parse ("127.0.0.1");
ถุงเท้าIPEndPoint ส่วนตัว
;
Form1 สาธารณะ ()
{
เตรียมใช้งานส่วนประกอบ ()
;
โมฆะส่วนตัว btConnect_Click (ผู้ส่งวัตถุ EventArgs e)
{
ลอง
{
serverFullAddr = IPEndPoint ใหม่ (serverIP, 1000);
sock
= ใหม่ Socket (AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
สร้างการเชื่อมต่อกับโฮสต์ระยะไกล
//เริ่มเธรดใหม่เพื่อรับข้อมูล
Thread t = new Thread(new ThreadStart(ReceiveMsg));
t.Name = "Receive Message";
// เธรดเป็นเธรดพื้นหลังหรือเธรดเบื้องหน้า เธรดพื้นหลังจะคล้ายกับเธรดเบื้องหน้า ยกเว้นว่าเธรดพื้นหลัง // ไม่ได้ป้องกันกระบวนการยุติ เมื่อเธรดเบื้องหน้าทั้งหมดที่เป็นของกระบวนการสิ้นสุดลง รันไทม์ภาษาทั่วไป // จะสิ้นสุดกระบวนการโดยการเรียกยกเลิกบนเธรดพื้นหลังใดๆ ที่ยังคงใช้งานอยู่
t.IsBackground = true;
t.Start();
}
catch(
ข้อยกเว้น เช่น)
{
MessageBox.Show(ex.Message)
;
ส่วนตัวเป็นโมฆะ ReceiverMsg()
{
ลอง
{
ในขณะที่
(จริง)
{
ไบต์ [] byteRec = ไบต์ใหม่ [100];
this.sock.Receive (byteRec);
string strRec = System.Text.Encoding.UTF8.GetString (byteRec);
(this.rtbReceive.InvoidRequired)
{
this.rtbReceive.Inrigg (new EventHandler(
ChangeRtb), new object[]
{ strRec, EventArgs.Empty });
catch
(ข้อยกเว้น เช่น)
{
MessageBox.Show
("รับข้อความผิดพลาด "+เช่นข้อความ);
}
}
โมฆะส่วนตัว ChangeRtb (วัตถุ obj, EventArgs e)
{
string s = System.Convert.ToString (obj);
this.rtbReceive.AppendText
(s + Environment.NewLine)
โมฆะส่วนตัว btSend_Click (ผู้ส่งวัตถุ EventArgs e)
{
ไบต์ [] byteSend =
System.Text.Encoding.UTF8.GetBytes (this.tbSend.Text.ToCharArray ());
ลอง
{
this.sock.Send (byteSend
}
)
{
MessageBox.Show("ส่งข้อความผิดพลาด"
)
;
โมฆะส่วนตัว btClose_Click (ผู้ส่งวัตถุ EventArgs e)
{
ลอง
{
this.sock.Shutdown(SocketShutdown.Receive);
this.sock.Close();
Application.Exit();
}
catch
{
MessageBox.Show("Exit Error") ;
} }
}
}
ปริศนา
:
คำสั่งที่มีเครื่องหมายสีแดงบนฝั่งไคลเอ็นต์: this.sock.Shutdown(SocketShutdown.Receive) หากเปลี่ยนเป็น
this.sock.Shutdown(SocketShutdown.Both); หรือ this.sock.Shutdown(SocketShutdown. ส่ง)
จากนั้นเมื่อคลิกปุ่มปิด การใช้งาน CPU จะพุ่งสูงขึ้นเป็น 100% อย่างไรก็ตาม การใช้ this.sock.Shutdown(SocketShutdown.Receive)
หรือไม่เรียกใช้เมธอด Shutdown() ลูกค้าไม่ควรใช้ Shutdown()?
http://www.cnblogs.com/KissKnife/archive/2006/08/13/475707.html