基于Socket服务器端实现本例主要是建立多客户端与服务器之间的数据传输,首先设计服务器。打开VS2008,在D:\C#\ch17目录下建立名为SocketServer的Windows应用程序。打开工程,往当前窗体中添加控件,如表17-6所示。
表17-6 添加控件列表
控 件
Name
Text
ListBox
lbInfo
Label
label
Button
button1
启动服务器
设计好的界面如图17-2所示。
接下来开始运用前面的知识设计服务器,主要分为以下步骤。
(1)首先是对一些命名空间的包含,包括System.Net、System.Net.Sockets、System.IO和System.Threading。然后定义一系列的全局变量,如下所示。
private Socket s;
//定义Socket对象
private Thread th;
//客户端连接服务器的线程
public Socket cSocket;
//单个客户端连接的Socket对象
public NetworkStream ns;
//网络流
public StreamReader sr;
//流读取
public StreamWriter sw;
//流写入
private delegate void SetTextCallback();
//用于操作主线程控件
(2)接下来是设计客户端连接的管理,主要包括服务器与客户端之间的连接和收发数据问题,,把它们放在一个函数Communication里,如下所示。
public void Communication()
{
while (true)
{
try
{
cSocket = s.Accept();
//用cSocket来代表该客户端连接
if (cSocket.Connected)
//测试是否连接成功
{
ns = new NetworkStream(cSocket); //建立网络流,便于数据的读取
sr = new StreamReader(ns);
//实例化流读取对象
sw = new StreamWriter(ns);
//实例化写入流对象
test();
//从流中读取
sw.WriteLine("收到请求,允许连接"); //向流中写入数据
sw.Flush();
//清理缓冲区
}
else
{
MessageBox.Show("连接失败");
}
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message);
//捕获Socket异常
}
catch (Exception es)
{
MessageBox.Show("其他异常" + es.Message);
//捕获其他异常
}
}
}
//以下代码的用法在第16章有关线程的用法时曾提到过,主要用于从当前线程操作主线程中的控件,这里就不在赘//述
public void send()
{
lbInfo.Items.Add(sr.ReadLine()+"\n");
}
public void test()
{
SetTextCallback stcb = new SetTextCallback(send);
Invoke(stcb);
}
(3)定义好与客户端的连接后,接下来需要利用线程来启动,双击“启动服务器”按钮,添加如下代码。
button1.Enabled = false;
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建Socket对象
IPAddress serverIP = IPAddress.Parse("222.18.142.171");
IPEndPoint server = new IPEndPoint(serverIP,13); //实例化服务器的IP和端口
s.Bind(server);
s.Listen(10);
try
{
th = new Thread(new ThreadStart(Communication));
//创建线程
th.Start();
//启动线程
label1.Text = "服务器启动成功!";
}
catch(Exception ex)
{
MessageBox.Show("服务器启动失败!" + ex.Message);
}
(4)最后在关闭服务器窗口的时候,还应该关闭线程和当前Socket连接,代码如下所示。
protected override void Dispose(bool disposing)
{
try
{
if (disposing && (components != null))
{
components.Dispose();
th.Abort();
//禁用当前Socket连接中的数据收发
s.Shutdown(System.Net.Sockets.SocketShutdown.Both);
s.Close();
}
base.Dispose(disposing);
}
catch
{
return;
}
}
//接着为当前窗体的FormClosed事件添加如下代码。
this.Close();