添加项目文件。
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SimpleCommunication
|
||||
{
|
||||
public class Client : IDisposable
|
||||
{
|
||||
#region DataMember & Ctor
|
||||
public TcpClient tcpclient;
|
||||
private NetworkStream netstream;
|
||||
public string IP;
|
||||
public string Port;
|
||||
private byte[] readBytes;
|
||||
private object tcpClientLock = new object();//锁TcpClient;Dispose之后就不允许EndRead,远程连接断开以后,就不允许再调用Dispose
|
||||
private bool closed = false;//包括本地主动断开和远程断开
|
||||
|
||||
//在事务处理结束后才触发下列事件
|
||||
public event DlgNoParam ConnectFailEvent;
|
||||
public event DlgOneParam<string> NewClientEvent;
|
||||
public event DlgOneParam<string> RecvMsgEvent;
|
||||
public event DlgOneParam<string> RemoteDisconnectEvent;
|
||||
public event DlgNoParam LocalDisconnectEvent;
|
||||
/// <summary>
|
||||
/// 客户端是否链接
|
||||
/// </summary>
|
||||
public bool IsConnected => (tcpclient != null && tcpclient.Connected) ? true : false;
|
||||
/// <summary>
|
||||
/// 服务的client的构造函数
|
||||
/// </summary>
|
||||
/// <param name="tcpclient"></param>
|
||||
public Client(TcpClient tcpclient)
|
||||
{
|
||||
this.tcpclient = tcpclient;
|
||||
readBytes = new byte[tcpclient.ReceiveBufferSize];//接收数据的缓冲区大小,如果太小一段数据会多次接收完成
|
||||
netstream = tcpclient.GetStream();//如果远程客户端断开一样可以获得netstream
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户端client的构造函数
|
||||
/// </summary>
|
||||
public Client()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 数据收发
|
||||
|
||||
/// <summary>
|
||||
/// 在建立连接的情况下发送消息
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
public bool SendMsg(string msg)
|
||||
{
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
if (netstream != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(msg))
|
||||
{
|
||||
byte[] buff = Encoding.Default.GetBytes(msg);
|
||||
netstream.Write(buff, 0, buff.Length);
|
||||
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 服务的接收到客户端连接后最先做的操作之一,客户端接收数据线程起始
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool BeginRead()
|
||||
{
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
IP = (tcpclient.Client.RemoteEndPoint as IPEndPoint).Address.ToString();
|
||||
Port = (tcpclient.Client.RemoteEndPoint as IPEndPoint).Port.ToString();
|
||||
if (NewClientEvent != null)
|
||||
{
|
||||
NewClientEvent(IP + " " + Port);
|
||||
}
|
||||
netstream.BeginRead(readBytes, 0, readBytes.Length, EndRead, null);//如果远程客户端断开这句话一样可以执行
|
||||
result = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有互斥资源
|
||||
/// 接收数据,远程连接断开,远程程序关闭,本地连接断开,都会按顺序调用进来;因为连接关闭后不再调用BeginRead
|
||||
/// 服务器listener.stop时不会进入这个函数,客户端照样通讯,服务端只是不能接收新连接而已
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
private void EndRead(IAsyncResult ar)
|
||||
{
|
||||
lock (tcpClientLock)
|
||||
{
|
||||
if (!closed)//如果本地主动断开就不会进入
|
||||
{
|
||||
try
|
||||
{
|
||||
string recvStr = "";
|
||||
int count = netstream.EndRead(ar);
|
||||
if (count > 0)
|
||||
{
|
||||
recvStr = Encoding.Default.GetString(readBytes, 0, count);
|
||||
recvStr = DateTime.Now.ToString("HH:mm:ss") + " [" + IP + " " + Port + "] :\n" + recvStr + "\n";
|
||||
if (RecvMsgEvent != null)
|
||||
{
|
||||
RecvMsgEvent(recvStr);
|
||||
}
|
||||
readBytes = new byte[tcpclient.ReceiveBufferSize];
|
||||
netstream.BeginRead(readBytes, 0, readBytes.Length, EndRead, null);
|
||||
}
|
||||
else//远程客户端主动断开
|
||||
{
|
||||
LocalClientClose();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message.Contains("无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接"))
|
||||
{
|
||||
LocalClientClose();
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalClientClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 客户端连接和关闭
|
||||
|
||||
/// <summary>
|
||||
/// 客户端的client连接服务器
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <param name="port"></param>
|
||||
/// <returns></returns>
|
||||
public bool Connect(ComboBox Server_IP, TextBox txtPort)
|
||||
{
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
|
||||
if (!string.IsNullOrEmpty(Server_IP.Text) && !string.IsNullOrEmpty(txtPort.Text))
|
||||
{
|
||||
IP = Server_IP.Text.Trim();
|
||||
Port = txtPort.Text.Trim();
|
||||
IPAddress ipAddress = IPAddress.Parse(IP);
|
||||
IPEndPoint point = new IPEndPoint(ipAddress, int.Parse(Port));
|
||||
tcpclient = new TcpClient(AddressFamily.InterNetwork);
|
||||
readBytes = new byte[tcpclient.ReceiveBufferSize];
|
||||
tcpclient.Connect(point);
|
||||
|
||||
netstream = tcpclient.GetStream();
|
||||
BeginRead();
|
||||
closed = false;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message.Contains("由于目标计算机积极拒绝"))
|
||||
{
|
||||
if (ConnectFailEvent != null)
|
||||
{
|
||||
ConnectFailEvent();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 远程连接断开后(点关闭断开,程序退出断开)本地连接处理
|
||||
/// </summary>
|
||||
public void LocalClientClose()
|
||||
{
|
||||
closed = true;
|
||||
DisposeEx();
|
||||
if (RemoteDisconnectEvent != null)
|
||||
{
|
||||
string param = IP + " " + Port;
|
||||
if (RemoteDisconnectEvent != null)
|
||||
{
|
||||
RemoteDisconnectEvent(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有互斥资源
|
||||
/// 在已连接条件下关闭本地连接和资源释放时调用
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
lock (tcpClientLock)
|
||||
{
|
||||
if (!closed)
|
||||
{
|
||||
closed = true;
|
||||
DisposeEx();
|
||||
if (LocalDisconnectEvent != null)
|
||||
{
|
||||
LocalDisconnectEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 由Dispose和LocalClientClose调用
|
||||
/// </summary>
|
||||
private void DisposeEx()
|
||||
{
|
||||
if (netstream != null)
|
||||
{
|
||||
netstream.Dispose();
|
||||
netstream = null;
|
||||
}
|
||||
if (tcpclient != null)
|
||||
{
|
||||
tcpclient.Close();
|
||||
tcpclient = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <数据结构类>
|
||||
/// 数据结构类
|
||||
/// </数据结构类>
|
||||
public class StateObject
|
||||
{
|
||||
//客户端Socket
|
||||
public Socket workSocket = null;
|
||||
//接收数据大小
|
||||
public const int BufferSize = 64;
|
||||
// 声明接收数据
|
||||
public byte[] buffer = new byte[BufferSize];
|
||||
// 接收数据的内容
|
||||
public StringBuilder sb = new StringBuilder();
|
||||
/// <summary>
|
||||
/// 通信方网络地址
|
||||
/// </summary>
|
||||
public EndPoint SEndPoint;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user