admin管理员组文章数量:1794759
Socket
同步: Accept Connect
Receive
异步: BeginAccept EndAccept
BeginReceive EndReceive
TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP时一种流式协议
流式协议的特点是什么?就像流水连续不断那样,消息之间没有边界。例如send了3条消息(这里的“消息”是指应用层的一个完整的协议包),分别是100字节、50字节、80字节,recv时可能收到的是230字节,就是说一次recv收到了3条消息,需要应用逻辑自己对recv到的数据进行分析,得出完整的消息。能一次recv到多个消息,也可能一次recv到一个半消息或半个消息,都是有可能的,这就是流式协议的特点。
TCP代码实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
/*IPEndPoint类包含应用程序连接到主机上的服务所需的主机和端口信息,通过组合服务的主机IP地址和端口号,IPEndPoint类形成到服务的连接点。*在IPEndPoint类中有两个很有用的构造函数:*public IPEndPoint(long, int); *public IPEndPoint(IPAddress, int);*它们的作用就是用指定的地址和端口号初始化IPEndPoint类的新实例*/
namespace Socket_TCP协议_服务器端
{class Program{static void Main(string[] args){//创建SocketSocket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//绑定IP和端口号 192.168.0.104IPAddress address = new IPAddress(new byte[]{192,168,0,104});//或者IPAddress address = IPAddress.Parse(192,168,0,104);EndPoint endPoint = new IPEndPoint(address,7788);//IPEndPoint对IP和端口做了一层封装的类tcpServer.Bind(endPoint);//绑定IP和端口号tcpServer.Listen(100);//开始监听端口号Socket clientSocket = tcpServer.Accept();//接受一条客户端连接//向客户端发送消息string str = "Hello 欢迎使用";byte[] data= Encoding.UTF8.GetBytes(str);clientSocket.Send(data);//接受客户端的消息byte[] data2 = new byte[1024];int length = clientSocket.Receive(data2);string message = Encoding.UTF8.GetString(data2, 0, length);Console.WriteLine(message);Console.ReadKey();}}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;namespace Socket__客户端
{class Program{static void Main(string[] args){Socket tcpSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);IPAddress ipaddress = IPAddress.Parse("192.168.0.104");EndPoint end = new IPEndPoint(ipaddress,7788);tcpSocket.Connect(end);byte[] data = new byte[1024];int length = tcpSocket.Receive(data);string str = Encoding.UTF8.GetString(data, 0, length);Console.WriteLine(str);string message = Console.ReadLine();byte[] data2 = Encoding.UTF8.GetBytes(message);tcpSocket.Send(data2);Console.ReadKey();}}
}
修改服务器端代码,将其改为异步处理客户端连接请求和服务器端异步接受消息:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;namespace tcp服务器端
{class Program{static void Main(string[] args){StartSeverASync();Console.ReadKey();}public static void StartSeverASync() //异步接收{Socket tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress address = IPAddress.Parse("192.168.1.111");IPEndPoint endPoint = new IPEndPoint(address, 7788);tcpSocket.Bind(endPoint);tcpSocket.Listen(10);//Socket clientSocket = tcpSocket.Accept();tcpSocket.BeginAccept(AcceptCallBack,tcpSocket);}static void AcceptCallBack(IAsyncResult ar){Socket tcpSocket = ar.AsyncState as Socket;Socket clientSocket = tcpSocket.EndAccept(ar);string str = "Hallo ,Client!";byte[] bytes = Encoding.UTF8.GetBytes(str);clientSocket.Send(bytes);clientSocket.BeginReceive(bytes2, 0, 1024, SocketFlags.None, ReceiveCallback, clientSocket);//这是开始异步接收数据tcpSocket.BeginAccept(AcceptCallBack, tcpSocket);//循环链接}static byte[] bytes2 = new byte[1024];//接收到消息后调用该方法static void ReceiveCallback(IAsyncResult ar) //回调方法{Socket clientSocket = ar.AsyncState as Socket;int count = clientSocket.EndReceive(ar);string str2 = Encoding.UTF8.GetString(bytes2, 0, count);Console.WriteLine("从客户端接收到消息:"+str2);clientSocket.BeginReceive(bytes2, 0, 1024, SocketFlags.None, ReceiveCallback, clientSocket);//循环接收消息}
实现异步接收消息:
此时关闭客户端,(非正常关闭)会报异常:
对异常进行处理:
static void ReceiveCallback(IAsyncResult ar) //回调方法{Socket clientSocket = null;try{clientSocket = ar.AsyncState as Socket;int count = clientSocket.EndReceive(ar);string str2 = Encoding.UTF8.GetString(bytes2, 0, count);Console.WriteLine("从客户端接收到消息:" + str2);clientSocket.BeginReceive(bytes2, 0, 1024, SocketFlags.None, ReceiveCallback, clientSocket);//循环接收消息}catch (Exception e){Console.WriteLine(e);}}
对客户端发送消息的方法进行改写,使其能正常关闭:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;namespace 客户端
{class Program{static void Main(string[] args){Socket tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress address = IPAddress.Parse("192.168.1.111");IPEndPoint endPoint = new IPEndPoint(address, 7788);tcpSocket.Connect(endPoint);byte[] data2 = new byte[1024];int length = tcpSocket.Receive(data2);string str2 = Encoding.UTF8.GetString(data2, 0, length);Console.WriteLine(str2);while (true){string str = Console.ReadLine();if (str == "c"){tcpSocket.Close();return;}byte[] data = Encoding.UTF8.GetBytes(str);tcpSocket.Send(data);}Console.ReadKey();}}
}
当我们按下c正常关闭时,服务器端会一直接收到空字符串:
此时,修改服务器端接收消息的代码:
static void ReceiveCallback(IAsyncResult ar) //回调方法{Socket clientSocket = null;try{clientSocket = ar.AsyncState as Socket;int count = clientSocket.EndReceive(ar);if (count == 0)//当接受的消息长度为0时,关闭clientSocket{clientSocket.Close();return;}string str2 = Encoding.UTF8.GetString(bytes2, 0, count);Console.WriteLine("从客户端接收到消息:" + str2);clientSocket.BeginReceive(bytes2, 0, 1024, SocketFlags.None, ReceiveCallback, clientSocket);//循环接收消息}catch (Exception e){Console.WriteLine(e);}}
可处理客户端正常/非正常关闭
——结束——
本文标签: Socket
版权声明:本文标题:Socket 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1692795126a203487.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论