7-3  TCP网络编程

本节学习目标:
n掌握TCP类的使用
n掌握TcpListener类和TcpClient类基本方法

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 案例学习:简单的通信程序

本次实验目标是使用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-1 网络编程技术(中) _休闲
7-5 信息传输
问题讨论:
1TcpListener启动监听和TcpClient对象连接到服务端?
先启动监听,然后才能在客户端发生连接。因为TCP是面向连接的协议,在发送数据之前,应先将套接字与IP地址和端口绑定,并处于监听状态。