TCP\IP 是什么?
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
Socket 是什么?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
// TCP/IP
using System.Net;
using System.Net.Sockets;
namespace TCPIP异步通讯
{
public class TCP_Server
{
public TCP_Server(string Ip, int Port)
{
this.ipAndPoint = new IPEndPoint(IPAddress.Parse(Ip), Port);
this.mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public DataExchange tmp = new DataExchange();
public delegate void DelDataArrived(DataExchange tmp);
public event DelDataArrived OnDataArrivedEvent; //收到数据事件
public event DelDataArrived OnDiscoveredDeviceEvent; //发现设备事件
///
/// IP地址和Port口
///
private IPEndPoint _IpAndPoint;
public IPEndPoint ipAndPoint
{
get {
return _IpAndPoint; }
set {
_IpAndPoint = value; }
}
///
/// 负责监听的Socket对象
///
private Socket _MySocket;
public Socket mySocket
{
get {
return _MySocket; }
set {
_MySocket = value; }
}
///
/// 负责收发数据的Socket对象
///
private Socket _ConnectSocket;
public Socket ConnectSocket
{
get {
return _ConnectSocket; }
set {
_ConnectSocket = value; }
}
///
/// 服务器开始监听
///
public void StartListen()
{
mySocket.Bind(ipAndPoint);
mySocket.Listen(10);
mySocket.BeginAccept(new AsyncCallback((iResult) =>
{
this.ConnectSocket = mySocket.EndAccept(iResult);
if (this.ConnectSocket.Connected)
{
if (OnDiscoveredDeviceEvent != null)
{
tmp.ip = this.ConnectSocket.RemoteEndPoint;
OnDiscoveredDeviceEvent(tmp);
}
Task task = ReceiveDataFromClient(this.ConnectSocket);
}
}), null);
}
public Task ReceiveDataFromClient(Socket rcvSocket)
{
return Task.Run(() =>
{
using (rcvSocket)
{
while (true)
{
byte[] byt = new byte[1024];
int len = rcvSocket.Receive(byt, 0, byt.Length, SocketFlags.None);
tmp.data = Encoding.Default.GetString(byt, 0, len);
if (OnDataArrivedEvent != null)
{
OnDataArrivedEvent(tmp);
}
}
}
});
}
///
/// 发送数据给客户端
///
///
public void Send(string Msg)
{
try
{
byte[] bytStr = Encoding.Default.GetBytes(Msg);
this.ConnectSocket.BeginSend(bytStr, 0, bytStr.Length, SocketFlags.None, new AsyncCallback((iar) =>
{
Socket Skt = (Socket)iar.AsyncState;
int length = this.ConnectSocket.EndSend(iar);
}), this.ConnectSocket);
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
}
///
/// 数据交换类,用于传递数据
///
public class DataExchange : EventArgs
{
private EndPoint _IP;
public EndPoint ip
{
get {
return _IP; }
set {
_IP = value; }
}
private Socket _TmpSkt;
public Socket tmpSkt
{
get {
return _TmpSkt; }
set {
_TmpSkt = value; }
}
private string _Data;
public string data
{
get {
return _Data; }
set {
_Data = value; }
}
}
客户端——上代码:
// TCP/IP
using System.Net;
using System.Net.Sockets;
namespace TCPIP异步通讯
{
public class TCP_Client
{
public TCP_Client(string Ip, int Port)
{
this.ipAndPoint = new IPEndPoint(IPAddress.Parse(Ip), Port);
this.mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public DataExchange_Client tmp = new DataExchange_Client();
public delegate void DelDataArrived(DataExchange_Client tmp);
public event DelDataArrived OnDataArrivedEvent; //收到数据事件
///
/// IP地址和Port口
///
private IPEndPoint _IpAndPoint;
public IPEndPoint ipAndPoint
{
get {
return _IpAndPoint; }
set {
_IpAndPoint = value; }
}
///
/// 负责连接的Socket对象
///
private Socket _MySocket;
public Socket mySocket
{
get {
return _MySocket; }
set {
_MySocket = value; }
}
///
/// 负责收发数据的Socket对象
///
private Socket _ConnectSocket;
public Socket ConnectSocket
{
get {
return _ConnectSocket; }
set {
_ConnectSocket = value; }
}
public void StartConnect()
{
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mySocket.BeginConnect(ipAndPoint, new AsyncCallback((iar) =>
{
Socket mySkt = (Socket)iar.AsyncState;
mySocket.EndConnect(iar);
Task taks = ReceiveDataFromServer(mySocket);
}), null);
}
public Task ReceiveDataFromServer(Socket rcvSocket)
{
return Task.Run(() =>
{
using (rcvSocket)
{
do
{
byte[] readBuffer = new byte[1024];
int readLen = rcvSocket.Receive(readBuffer, 0, readBuffer.Length, SocketFlags.None);
if (OnDataArrivedEvent != null)
{
tmp.data = Encoding.Default.GetString(readBuffer, 0, readLen);
OnDataArrivedEvent(tmp);
}
}
while (true);
}
});
}
public void Send(string Msg)
{
try
{
byte[] bytStr = Encoding.Default.GetBytes(Msg);
mySocket.BeginSend(bytStr, 0, bytStr.Length, SocketFlags.None, new AsyncCallback((iar) =>
{
Socket Skt = (Socket)iar.AsyncState;
int length = mySocket.EndSend(iar);
}), mySocket);
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
}
///
/// 数据交换类,用于传递数据
///
public class DataExchange_Client : EventArgs
{
private EndPoint _IP;
public EndPoint ip
{
get {
return _IP; }
set {
_IP = value; }
}
private Socket _TmpSkt;
public Socket tmpSkt
{
get {
return _TmpSkt; }
set {
_TmpSkt = value; }
}
private string _Data;
public string data
{
get {
return _Data; }
set {
_Data = value; }
}
}
}
服务器调用:
DataExchange tmp = new DataExchange();
TCP_Server Server = new TCP_Server(string ip, int port);
//订阅发现设备事件
Server.OnDiscoveredDeviceEvent += new TCP_Server.DelDataArrived((tmp) =>
{
//编写发现客户端后要做的事。。。
string ip = tmp.ip;
}
//订阅接收数据事件
Server.OnDataArrivedEvent += new TCP_Server.DelDataArrived((tmp) =>
{
//编写接收到数据之后要做的事。。。
string data = tmp.data;
}
//开始监听
Server.StartListen();
客户端调用:
DataExchange_Client tmp = new DataExchange_Client();
TCP_Client Client = new TCP_Client(string ip, int port);
Client.OnDataArrivedEvent += new TCP_Client.DelDataArrived((tmp) =>
{
//编写收到服务器的数据后执行的代码
string data = tmp.data;
});
//开始连接
Client.StartConnect();
以上代码有一个不足就是,服务器可以接收多个客户端发来的数据,但是无法发送数据给多个客户端,因为负责通信的Socket对象已经被写成唯一的了。
如果需要发送数据给多个客户端,则可以将服务器 Accept 到的Socket对象依次添加在一个集合中,并在Send() 方法参数列表中将Socket类型对象传入,调用 Send() 方法。如下:
///
/// 发送数据给客户端
/// 发送数据的Socket对象
/// 要发送的数据
public void Send(Socket skt, string Msg)
{
try
{
byte[] bytStr = Encoding.Default.GetBytes(Msg);
skt.BeginSend(bytStr, 0, bytStr.Length, SocketFlags.None, new AsyncCallback((iar) =>
{
Socket Skt = (Socket)iar.AsyncState;
int length = skt.EndSend(iar);
}), skt);
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
以上,如有错误,欢迎及时批评指正,谢谢。。。