www.pudn.com > tcpipserver.rar > FormServer.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
//添加的命名空间
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace WindowsApplication1
{
public partial class FormServer : Form
{
private bool isExit = false;
//保存连接的所有客户端
System.Collections.ArrayList clientList = new System.Collections.ArrayList();
TcpListener listener;
//用于一个线程操作另一个线程的控件
private delegate void SetListBoxCallback(string str);
private SetListBoxCallback setListBoxCallback;
private delegate void SetRichTextBoxCallback(string str);
private SetRichTextBoxCallback setRichTextBoxCallback;
private delegate void SetComboBoxCallback(string str);
private SetComboBoxCallback setComboBoxCallback;
private delegate void RemoveComboBoxItemsCallback(ReadWriteObject readWriteObject);
private RemoveComboBoxItemsCallback removeComboBoxItemsCallback;
//用于线程同步,初始状态设为非终止状态,使用手动重置方式
private EventWaitHandle allDone = new EventWaitHandle(false, EventResetMode.ManualReset);
public FormServer()
{
InitializeComponent();
listBoxStatus.HorizontalScrollbar = true;
setListBoxCallback = new SetListBoxCallback(SetListBox);
setRichTextBoxCallback = new SetRichTextBoxCallback(SetComboBox);
setComboBoxCallback = new SetComboBoxCallback(SetComboBox);
removeComboBoxItemsCallback = new RemoveComboBoxItemsCallback(RemoveComboBoxItems);
}
private void buttonStart_Click(object sender, EventArgs e)
{
//由于服务器要为多个客户端服务,所以需要创建一个线程监听客户端的连接请求
ThreadStart ts = new ThreadStart(AcceptConnect);
Thread myThread = new Thread(ts);
myThread.Start();
buttonSend.Enabled = false;
buttonStop.Enabled = true;
}
private void AcceptConnect()
{
//获取本机所有IP地址
IPAddress[] ip = Dns.GetHostAddresses(Dns.GetHostName());
listener = new TcpListener(ip[0], 51888);
listener.Start();
while(isExit==false)
{
try
{
//将时间的状态设为非终止
allDone.Reset();
AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallback);
listBoxStatus.Invoke(setListBoxCallback, "开始等待客户连接");
//开始一个异步操作接受传入的连接尝试
listener.BeginAcceptTcpClient(callback, listener);
//阻塞当前线程,直到收到客户连接信号
allDone.WaitOne();
}
catch (Exception err)
{
listBoxStatus.Invoke(setListBoxCallback, err.Message);
break;
}
}
}
//ar是IAsycResult类型的接口,表示异步操作的状态
//是由listener.BeginAcceptTcpClient(callback, listener)传递过来的
private void AcceptTcpClientCallback(IAsyncResult ar)
{
try
{
//将事件状态设为终止状态,允许一个或多个等待线程继续
allDone.Set();
TcpListener mylistener = (TcpListener)ar.AsyncState;
//异步接受传入的连接,并创建新的TcpClient对象处理远程主机通信
TcpClient client = mylistener.EndAcceptTcpClient(ar);
listBoxStatus.Invoke(setListBoxCallback, "已接受客户连接:" + client.Client.RemoteEndPoint);
comboBox1.Invoke(setComboBoxCallback, client.Client.RemoteEndPoint);
ReadWriteObject readWriteObject = new ReadWriteObject(client);
clientList.Add(readWriteObject);
SendString(readWriteObject, "服务器已经接受连接,请通话!");
readWriteObject.netStream.BeginRead(readWriteObject.readBytes, 0, readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
}
catch(Exception err)
{
listBoxStatus.Invoke(setListBoxCallback, err.Message);
}
}
private void ReadCallback(IAsyncResult ar)
{
try
{
ReadWriteObject readWriteObject = (ReadWriteObject)ar.AsyncState;
int count = readWriteObject.netStream.EndRead(ar);
richTextBoxReceive.Invoke(setRichTextBoxCallback, string.Format("[来自{0}]{1}", readWriteObject.client.Client.RemoteEndPoint, System.Text.Encoding.UTF8.GetString(readWriteObject.readBytes, 0, count)));
if (isExit == false)
{
readWriteObject.InitReadArray();
readWriteObject.netStream.BeginRead(readWriteObject.readBytes, 0, readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
}
}
catch(Exception err)
{
listBoxStatus.Invoke(setListBoxCallback, err.Message);
}
}
private void SendString(ReadWriteObject readWriteObject, string str)
{
try
{
readWriteObject.writeBytes = System.Text.Encoding.UTF8.GetBytes(str + "\r\n");
readWriteObject.netStream.BeginWrite(readWriteObject.writeBytes, 0, readWriteObject.writeBytes.Length, new AsyncCallback(SendCallback), readWriteObject);
readWriteObject.netStream.Flush();
listBoxStatus.Invoke(setListBoxCallback, string.Format("向{0}发送:{1}", readWriteObject.client.Client.RemoteEndPoint, str));
}
catch (Exception err)
{
listBoxStatus.Invoke(setListBoxCallback, err.Message);
}
}
private void SendCallback(IAsyncResult ar)
{
ReadWriteObject readWriteObject = (ReadWriteObject)ar.AsyncState;
try
{
readWriteObject.netStream.EndWrite(ar);
}
catch(Exception err)
{
listBoxStatus.Invoke(setListBoxCallback, err.Message);
comboBox1.Invoke(removeComboBoxItemsCallback, readWriteObject);
}
}
private void RemoveComboBoxItems(ReadWriteObject readWriteObject)
{
int index = clientList.IndexOf(readWriteObject);
comboBox1.Items.RemoveAt(index);
}
private void SetListBox(string str)
{
listBoxStatus.Items.Add(str);
listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1;
listBoxStatus.ClearSelected();
}
private void SetReceiveText(string str)
{
richTextBoxReceive.AppendText(str);
}
private void SetComboBox(object obj)
{
comboBox1.Items.Add(obj);
}
//停止监听 按钮的click事件
private void buttonStop_Click(object sender, EventArgs e)
{
//使线程自动结束
isExit = true;
//将事件状态设置为终止状态,允许一个或多个等待线程继续
//从而使线程正常结束
allDone.Set();
buttonSend.Enabled = true;
buttonStop.Enabled = false;
}
//发送
private void buttonSend_Click(object sender, EventArgs e)
{
int index = comboBox1.SelectedIndex;
if (index == -1)
{
MessageBox.Show("请先选择接收方,然后再单击[发送]");
}
else
{
ReadWriteObject obj = (ReadWriteObject)clientList[index];
SendString(obj, richTextBoxSend.Text);
richTextBoxSend.Clear();
}
}
//关闭窗口前触发的事件
private void FormServer_FormClosing(object sender, FormClosedEventArgs e)
{
buttonStop_Click(null, null);
}
}
}