不得不承認,寫的又臭又長的,又不好理解。
====ServerSocket.cs====
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;//for Thread
using System.Threading.Tasks;
using System.Net;//for IPEndPoint
using System.Net.Sockets;//for Socket
using System.Windows.Forms;//for MessageBox
namespace HelloServerSocket
{
public class TServerSocket
{
//----宣告委派----
public delegate void SynchronizeMethod();//萬用委派函式
public delegate void _OnRead(object sender, byte[] buf, int len);//收到訊息的委派函式
public delegate void _OnError(object sender, Socket socket, int ErrorCode);//收到訊息的委派函式
public delegate void _OnConnect(object sender, Socket socket);//收到訊息的委派函式
public delegate void _OnDisconnect(object sender, Socket socket);//收到訊息的委派函式
//使用Invoke 呼叫萬用委派函式
public void Synchronize(SynchronizeMethod Method)
{
while (!Owner.InvokeRequired) ;
Owner.Invoke(Method);
}
//其他地方不會用到,因此用巢式class
public class TConnection
{
public Socket Socket;
//聽訊息用
public Thread thread;
//離開執行序用
private bool bStop = false;
//跟著釋放
private Form Owner;
//我的收到訊息的事件
/// <summary>
/// 實做public void OnRead(object sender, byte[] buf, int len)函式,並帶入TClientSocket.OnRead。
/// </summary>
public _OnRead OnRead = null;
/// <summary>
/// 實做public void OnError(object sender, Socket socket, int ErrorCode)函式,並帶入TClientSocket.OnError。
/// </summary>
public _OnError OnError = null;
public _OnDisconnect OnDisconnect = null;
//建構子
public TConnection(Form Owner, Socket s)
{
Socket = s;
//會跟著釋放
this.Owner = Owner;
if (Owner == null)
{
MessageBox.Show("Owner 不可為空值");
}
}
private byte[] tmp_buf = null;
private int tmp_len = 0;
//聽訊息(執行序內的程式)
private void Listent()
{
while (true)
{
//降CPU Load用
Thread.Sleep(1);
//如果有代入事件,就觸發
if (OnRead != null)
{
/*
int len = Socket.Available;//取得Receive Size
if(len>0)
{
byte[] buf=new byte[len];
Socket.Receive(buf);
}
//這個方法可行,但就沒辦法知道斷線,不然原本我想就直接丟Socket回去OnRead。
*/
//值接帶buf去接
byte[] buf=new byte[1024];
int len = Socket.Receive(buf);//當沒有資料時,會一直停在這裡,但斷線時會回傳0。
tmp_buf = buf;
tmp_len = len;
if (len == 0) break;
Synchronize(Sync_Read);
}
if (bStop) break;
if (Owner.Disposing) break;
}
//不斷線就關閉程式,BCB伺服端會出現ErrorCode:10053
if (OnDisconnect != null) Synchronize(Sync_Disconnect);
if (!Socket.Connected)
{
Socket.Shutdown(SocketShutdown.Both);
Socket.Disconnect(true);
Socket.Close();
}
Socket = null;
}
//避免代入程式有使用到可視元件,使用Invoke呼叫委派函式
void Sync_Disconnect()
{
OnDisconnect(this, Socket);
}
//避免代入程式有使用到可視元件,使用Invoke呼叫委派函式
void Sync_Read()
{
OnRead(this, tmp_buf, tmp_len);
}
//使用Invoke 呼叫萬用委派函式
public void Synchronize(SynchronizeMethod Method)
{
while (!Owner.InvokeRequired);
Owner.Invoke(Method);
}
public void Connect()
{
thread = new Thread(Listent);
thread.Start();
}
public void Disconnect()
{
bStop = true;
}
}//end class TConnect
public List<TConnection> Connections=new List<TConnection>();
public int Port=8888;
private Form Owner;
private Socket FSocket = null;
//----宣告委派----
public _OnRead OnRead = null;
public _OnError OnError = null;
public _OnConnect OnConnect = null;
public _OnDisconnect OnDisconnect = null;
private Socket tmp_socket;
private int tmp_error;
//執行序,等待連線用
private Thread thread = null;
//離開執行序用
private bool bStop = false;
//建構子
public TServerSocket(Form Owner)
{
//會跟著釋放
this.Owner = Owner;
if (Owner == null)
{
MessageBox.Show("Owner 不可為空值");
}
FSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
FSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), Port));
FSocket.Listen(100);//最大連線數
}
//Server On
public void Active()
{
//建立執行序
thread = new Thread(WaitAccept);//帶入等待連線函式
thread.Start();//開始執行序
}
//Server On(多載)
public void Active(int port)
{
Port = port;
Active();
}
//Server Off
public void Deactive()
{
FSocket.Close();
bStop = true;
}
//等待連線
private void WaitAccept()
{
while (true)
{
//Client
Socket ClientSocket = null;
try
{
ClientSocket = FSocket.Accept();
if (OnConnect != null)
{
if (ClientSocket.Connected)
{
tmp_socket = ClientSocket;
Synchronize(Sync_Connect);
}
}
TConnection conn = new TConnection(Owner, ClientSocket);
conn.OnError = this.OnError;
conn.OnRead = this.OnRead;
conn.OnDisconnect = this.OnDisconnect;
Connections.Add(conn);
conn.Connect();
}
catch (SocketException e)
{
//FSocket.Accept()中。
//FSocket.Close()時,所造成的錯誤。
if (e.ErrorCode == 10004) break;
if (OnError != null)
{
tmp_socket = ClientSocket;
tmp_error = e.ErrorCode;
Synchronize(Sync_Error);
}
}
if (bStop) break;
}
foreach (TConnection conn in Connections)
{
conn.Disconnect();
}
}
public void Sync_Connect()
{
OnConnect(this, tmp_socket);
}
public void Sync_Error()
{
OnError(this, tmp_socket, tmp_error);
}
//傳送訊息
public void SendText(String Text)
{
foreach (TConnection conn in Connections)
{
if (conn == null) continue;
Byte[] bytesSend = Encoding.ASCII.GetBytes(Text);
conn.Socket.Send(bytesSend, bytesSend.Length, 0);
}
}
}//end class
}//end namespace
====Form1.cs====
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace HelloServerSocket
{
public partial class Form1 : Form
{
public TServerSocket ServerSocket;
public Form1()
{
InitializeComponent();
ServerSocket = new TServerSocket(this);
ServerSocket.OnConnect = ClientConnect;
ServerSocket.OnError = ClientError;
ServerSocket.OnRead = ClientRead;
ServerSocket.OnDisconnect = ClientDisconnect;
ServerSocket.Active();
}
public void ClientDisconnect(object sender, Socket socket)
{
textBox1.AppendText("Client Disconnect.\r\n");
}
public void ClientConnect(object sender, Socket socket)
{
textBox1.AppendText("Client Connect.\r\n");
}
public void ClientError(object sender, Socket socket, int ErrorCode)
{
textBox1.AppendText("Client Error:"+ErrorCode.ToString()+"\r\n");
}
public void ClientRead(object sender, byte[] buf, int len)
{
String msg = Encoding.ASCII.GetString(buf,0,len);
{
textBox1.AppendText(msg + "\r\n");
}
for (int i = 0; i < ServerSocket.Connections.Count; i++)
{
ServerSocket.Connections[i].Socket.Send(buf,len,0);
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
ServerSocket.Deactive();
}
}
}
留言列表