今天有个童鞋向我问了一下关于C#中的TCP操作,我当时给他讲了一下,感觉这个东西还是需要有代码才能讲清楚。这里我只贴异步的代码。异步看明白了,同步自然就不用多说了。
首先我说一下我讲解的代码的思路。
1.【准备好服务端】既然是客户端,那么首先我们需要一个服务端,我的服务端已经写好,本文暂时不讲服务端代码。
2.【客户端打开连接】类似于打电话一样,要两个手机之间打通了才能进行对话。这里我采用的是异步连接方式,代码如下
然后哦在AsynConnect方法中进行结束连接,如下图
3.【接收数据】既然打通了电话。那么就可以进行交流了。这里我们在连接成功插入了一段代码,表示开始进行数据接收操作,为了在等待接收数据的时候还能有其他操作,这里使用异步方式,如下图
这里只是开始异步读取数据,所以我们在AsynReceiveData方法中进行结束本次数据接收。如下图
4.【发送数据】打电话不能一个人说话对吧,此时我们在写了一个客户端向服务端发送数据请求的方法。不过这里发送我是采用的同步方式,因为数据少,发送的东西又不重要,没必要去异步。
5.总结一下,然后贴出整个代码。其实没啥说的,我下面这几行代码初学者都能看懂。这里面有一个比较重要的思维点就是:远程连接打开后马上就设置了开始异步数据接收,如果不做这一步,你不会接收到服务端的数据的。简单点,说话的方式点:就是我要开启了异步数据接收(BeginRead)才会正常接收到数据。还有一点就是这次的数据接收结束后,还要再次开启异步数据接收,这样才能正常结束到下一次的数据。
6.以下就是整个代码部分
/// <summary>
/// TcpClient操作
/// </summary>
public class TcpClientBusiness
{
#region 自定义参数
/// <summary>
/// Tcp客户端模型
/// </summary>
private static TcpClient tcpClient;
/// <summary>
/// 网络访问数据流
/// </summary>
private static NetworkStream networkStream;
/// <summary>
/// 返回数据
/// </summary>
public static List<byte[]> ResponseBytes = new List<byte[]>();
/// <summary>
/// 远程服务IP地址
/// </summary>
public static string RemoteIp = string.Empty;
/// <summary>
/// 远程服务IP地址对应端口
/// </summary>
public static int RemotePort = -1;
/// <summary>
/// 是否连接
/// </summary>
public static bool IsConnected = false;
#endregion
/// <summary>
/// 打开TCP连接
/// </summary>
public static void ConnectToServer()
{
try
{
//初始化TCP客户端对象
tcpClient = new TcpClient();
//开始连接
tcpClient.BeginConnect(RemoteIp, RemotePort, new AsyncCallback(AsynConnect), tcpClient);
}
catch (Exception ex)
{
VerficationOperate.WriteTextLogs("TcpClientBusiness", "ConnectToServer|异常消息:" + ex.Message.ToString());
}
}
/// <summary>
/// 异步连接
/// </summary>
/// <param name="iar"></param>
public static void AsynConnect(IAsyncResult iar)
{
try
{
//连接成功
tcpClient.EndConnect(iar);
//连接成功标志
IsConnected = true;
networkStream = tcpClient.GetStream();
byte[] TempBytes = new byte[1024];
//开始异步读取返回数据
networkStream.BeginRead(TempBytes, 0, TempBytes.Length, new AsyncCallback(AsynReceiveData), TempBytes);
}
catch (Exception ex)
{
VerficationOperate.WriteTextLogs("TcpClientBusiness", "AsynConnect|异常消息:" + ex.Message.ToString());
}
}
/// <summary>
/// 发送数据
/// <param name="SendBytes">需要发送的数据</param>
/// </summary>
public static void SendData(byte[] SendBytes)
{
try
{
if (networkStream.CanWrite && SendBytes != null && SendBytes.Length > 0)
{
//发送数据
networkStream.Write(SendBytes, 0, SendBytes.Length);
networkStream.Flush();
}
}
catch (Exception ex)
{
if (tcpClient != null)
{
tcpClient.Close();
//关闭连接后马上更新连接状态标志
IsConnected = false;
}
VerficationOperate.WriteTextLogs("TcpClientBusiness", "SendData|异常消息:" + ex.Message.ToString());
}
}
/// <summary>
/// 异步接受数据
/// </summary>
/// <param name="iar"></param>
public static void AsynReceiveData(IAsyncResult iar)
{
byte[] CurrentBytes = (byte[])iar.AsyncState;
try
{
//结束了本次数据接收
int num = networkStream.EndRead(iar);
//这里展示结果为InfoModel的CurrBytes属性,将返回的数据添加至返回数据容器中
ResponseBytes.Add(CurrentBytes);
//处理结果后马上启动数据异步读取【目前我每条接收的字节数据长度不会超过1024】
byte[] NewBytes = new byte[1024];
networkStream.BeginRead(NewBytes, 0, NewBytes.Length, new AsyncCallback(AsynReceiveData), NewBytes);
}
catch (Exception ex)
{
VerficationOperate.WriteTextLogs("TcpClientBusiness", "AsynReceiveData|异常消息:" + ex.Message.ToString());
}
}
}
强调以下,代码没有测试,不过直接复制上去肯定能用,不能用你来砍我。这个仅给初学者提供参考,至于TCP服务端代码,看看下次有空的话补上。