7-3  TCP网络编程<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

本节学习目标:

n 掌握TCP类的使用
n 掌握TcpListener类和TcpClient类基本方法

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />7-3-1 System.Net.Sockets命名空间

包含了一些相关类,允许直接发送TCP网络请求或者某个端口监听TCP网络请求。提供了 Windows Sockets接口的托管实现,主要成员,如表7-4所示:

说明

Socket

实现套接字接口

SocketException

发生套接字错误时引发的异常

TCP 网络服务提供客户端连接。

TCP 网络客户端侦听连接。

提供用户数据报 (UDP) 网络服务。

枚举

说明

指定 Socket 类的实例可以使用的寻址方案。

指定 Socket 类的实例可以使用的协议类型。

指定 Socket 类支持的协议。

指定套接字的发送和接收行为。

Socket.SetSocketOption Socket.GetSocketOption 方法定义套接字选项级别。

7-4

7-3-2  TCP

主要使用TCPClient类,为TCP网络服务提供连接,包括相关属性和方法来控制连接,通过流对象附带读写功能,主要成员,如表7-5所示:

方法

说明

Connect

使用指定的主机名和端口号将客户端连接到 TCP 主机。

GetStream

返回用于发送和接收数据的 NetworkStream

释放此 TcpClient 实例,而不关闭基础连接。

属性

说明

获取或设置基础 Socket

SendTimeout

获取或设置 TcpClient 等待发送操作成功完成的时间量。

SendBufferSize

获取或设置发送缓冲区的大小。

获取或设置在初始化一个读取操作以后 TcpClient 等待接收数据的时间量。

获取或设置接收缓冲区的大小。

7-5

TcpListener类用于监听和接收连接请求,如表7-6所示:

方法

说明

Start

开始侦听传入的连接请求。

接受挂起的连接请求。

关闭侦听器。

7-6

这里我们传输数据时,主要用到了NetworkStream,它代表的是网络中传输的数据流,在发生或接收数据时,可从流中获取字节数组或对应的字符串。主要成员,如表7-7所示:

方法

说明

Read

NetworkStream 读取数据。

ReadByte

从流中读取一个字节,并将流内的位置向前推进一个字节,或者如果已到达流的末尾,则返回 -1

Write

将数据写入 NetworkStream

将一个字节写入流内的当前位置,并将流内的位置向前推进一个字节。

属性

说明

获取流上可用数据的长度。

Socket

获取基础 Socket

7-7

1<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /> 案例学习:简单的通信程序

本次实验目标是使用Tcp相关类实现简单通信。

u  实验步骤(1):

新建一个Winform项目,并在当前新建项目的窗体上添加两个按钮和文本框。本案例用以实现在文本框中输入要传输的信息,在服务端应用程序中启动监听,接收来自客户端的消息。界面布局设置如图7-5左侧图像所示。

u  实验步骤(2):双击窗体界面,添加功能源代码如下:

/// <summary>

/// 启动 按钮的鼠标单击事件

/// </summary>

private void button1_Click(object sender, EventArgs e)

{

listen = new TcpListener(9999);

listen.Start();

   listBox1.Items.Add(" 服务器启动");

   Socket socket = listen.AcceptSocket();

   netstream = new NetworkStream(socket);

}

/// <summary>

/// 接收 按钮的鼠标单击事件

/// </summary>

private void btnReceive_Click(object sender, EventArgs e)

{

if (netstream.DataAvailable)

{

byte[] getdata = new byte[1024];

int length = netstream.Read(getdata, 0, getdata.Length);

string msg = Encoding.Default.GetString(getdata, 0, length);

listBox1.Items.Add(" 收到客户端消息>>");

listBox1.Items.Add(msg);

}

}

u 实验步骤(3):

再在当前项目中新建一个Winform窗体,并在窗体上添加一个按钮和文本框,界面布局及构成见图7-5右侧图片所示。本窗体实现目的是当用户在文本框中输入要传输的信息,点击“发送”按钮后,可以将文本框中输入的消息发送出去。

u 实验步骤(4):
    用鼠标双击“发送”按钮,添加功能源代码:

private void btnSend_Click(object sender, EventArgs e)

{

TcpClient client = new TcpClient();

client.Connect("localhost",9999);

netstream = client.GetStream();

if (txtMsg.Text.Trim() == "")

{

MessageBox.Show(" 消息不能为空");

return;

}

byte[] senddata = Encoding.Default.GetBytes(txtMsg.Text);

netstream.Write(senddata, 0, senddata.Length);

netstream.Flush();

}

将解决方案设置为多启动项目,同时启动两个应用程序,在客户端程序中输入消息,在服务端点击接收,可看到消息窗口的变化。如果与远程机器通信,只需将客户端部署到远程机器,并修改Client.Connect()中的连接地址和端口。这里看到的只是单向传输,双向传输则两端程序均需包含相同的发送接收数据的代码。

7-5 信息传输

问题讨论:

1 TcpListener启动监听和TcpClient对象连接到服务端?

先启动监听,然后才能在客户端发生连接。因为 TCP是面向连接的协议,在发送数据之前,应先将套接字与IP地址和端口绑定,并处于监听状态。