Socket通讯实例-基本Socket
连接握⼿:
1.客户端发送建⽴连接请求
2.服务端确认连接请求
3.客户端确认已经连接
以上3步完成后即可使⽤send recv了
断开握⼿:如果要正确断开必须经过4次握⼿。
1.客户端发送请求停⽌TCP连接请求
2.服务端收到请求后将这⼀个socket关闭
3.服务端发送反向请求客户端关闭socket连接
4.客户端确认服务端请求,关闭socket连接。
⽰例程序是同步套接字程序,功能很简单,只是客户端发给服务器⼀条信息,服务器向客户端返回⼀条信息;,是⼀个最基本的socket编程流程,依次记录套接字的同步和异步,以及它们的区别。
下⾯是⽰例程序的简单步骤说明
服务器端:
第⼀步:⽤指定的端⼝号和服务器的ip建⽴⼀个EndPoint对像;
第⼆步:建⽴⼀个Socket对像;
第三步:⽤socket对像的Bind()⽅法绑定EndPoint;
第四步:⽤socket对像的Listen()⽅法开始监听;
第五步:接受到客户端的连接,⽤socket对像的Accept()⽅法创建新的socket对像⽤于和请求的客户端进⾏通信;
第六步:通信结束后⼀定记得关闭socket;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Server
{
class Program
{
static void Main(string[] args) {
int port = 2000;//端⼝号码
string host = "127.0.0.1";//服务器主机
///创建终结点(EndPoint)
//IPAddress 类包含计算机在 IP ⽹络上的地址。
//IPAddress..Parse ⽅法 (将 IP 地址字符串转换为 IPAddress 实例。)
IPAddress ip = IPAddress.Parse(host);
//将⽹络端点表⽰为 IP 地址和端⼝号。
//IPEndPoint 类包含应⽤程序连接到主机上的服务所需的主机和本地或远程端⼝信息。
//通过组合服务的主机 IP 地址和端⼝号,IPEndPoint 类形成到服务的连接点。
IPEndPoint ipe = new IPEndPoint(ip, port);//⽤指定的地址和端⼝号初始化 IPEndPoint 类的新实例。
// end 终结的创建
//Socket经解
/
/Socket 类对异步⽅法遵循 .NET Framework 命名模式。例如,同步的 Receive ⽅法对应于异步的 BeginReceive 和 EndReceive ⽅法。
//如果应⽤程序在执⾏期间只需要⼀个线程,请使⽤下⾯的⽅法,这些⽅法适⽤于同步操作模式。
//如果当前使⽤的是⾯向连接的协议(如 TCP),则服务器可以使⽤ Listen ⽅法侦听连接。
// Accept ⽅法处理任何传⼊的连接请求,并返回可⽤于与远程主机进⾏数据通信的 Socket。可以使⽤此返回的 Socket 来调⽤ Send 或 Receive ⽅法。
//如果要指定本地 IP 地址和端⼝号,请在调⽤ Listen ⽅法之前先调⽤ Bind ⽅法。
//如果您希望基础服务提供程序为您分配可⽤端⼝,请使⽤端⼝号 0。
//如果希望连接到侦听主机,请调⽤ Connect ⽅法。若要进⾏数据通信,请调⽤ Send 或 Receive ⽅法。
//如果当前使⽤的是⽆连接协议(如 UDP),则根本不需要侦听连接。调⽤ ReceiveFrom ⽅法可接受任何传⼊的数据报。
// 使⽤ SendTo ⽅法可将数据报发送到远程主机。
//若要在执⾏过程中使⽤单独的线程处理通信,请使⽤下⾯的⽅法,这些⽅法适⽤于异步操作模式。
//如果当前使⽤的是⾯向连接的协议(如 TCP),则可使⽤ Socket、BeginConnect 和 EndConnect ⽅法来连接侦听主机。
// 通过使⽤ BeginSend 和 EndSend ⽅法,或者使⽤ BeginReceive 和 EndReceive ⽅法,可以进⾏异步数据通信。
//可以使⽤ BeginAccept 和 EndAccept 处理传⼊的连接请求。
//如果您使⽤的是 UDP 等⽆连接协议,则可以使⽤ BeginSendTo 和 EndSendTo 来发送数据报,⽽使⽤ BeginReceiveFrom 和 EndReceiveFrom 来接收数据报。
//如果对⼀个套接字执⾏多个异步操作,它们不⼀定按启动时的顺序完成。
//当数据发送和数据接收完成之后,可使⽤ Shutdown ⽅法来禁⽤ Socket。
//在调⽤ Shutdown 之后,可调⽤ Close ⽅法来释放与 Socket 关联的所有资源。
//通过 Socket 类,您可以使⽤ SetSocketOption ⽅法来配置 Socket。
/
/ 可以使⽤ GetSocketOption ⽅法来检索这些设置。
//说明:
//如果要编写相对简单的应⽤程序,⽽且不需要最⾼的性能,则可以考虑使⽤ TcpClient、TcpListener 和 UdpClient。
//这些类为 Socket 通信提供了更简单、对⽤户更友好的接⼝。
//Socket经解完成
//创建socket并开始监听
//创建⼀个socket对像,如果⽤udp协议,则要⽤SocketType.Dgram类型(⽆连接的)的套接字
//使⽤指定的地址族(socket使⽤的寻址⽅案)、套接字类型(Stream:双向连接)和协议(协议类型)
//初始化 Socket 类的新实例。
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//如果需要使⽤特定的本地终结点,请使⽤ Bind ⽅法。必须先调⽤ Bind,然后才能调⽤ Listen ⽅法。
//在调⽤ Bind 之前,必须⾸先创建打算从其进⾏数据通信的本地 IPEndPoint。
//如果您不介意分配哪个本地地址,则可以⽤ IPAddress..::.Any 作为地址参数创建⼀个 IPEndPoint,
//这样,基础服务提供程序将会分配最适合的⽹络地址。如果您有多个⽹络接⼝,这将有助于简化您的应⽤程序。
//如果您不介意使⽤哪个本地端⼝,则可以创建⼀个使⽤ 0 作为端⼝号的 IPEndPoint。
//在这种情况下,服务提供程序将会分配⼀个可⽤的端⼝号(介于 1024 和 5000 之间)。
//如果使⽤上⾯的⽅法,您可以通过调⽤ LocalEndPoint 获知所分配的本地⽹络地址和端⼝号。
//如果当前使⽤的是⾯向连接的协议,则直到您调⽤了 Connect 或 EndConnect ⽅法后,LocalEndPoint 才会返回本地分配的⽹络地址。
//如果当前使⽤的是⽆连接协议,则直到完成⼀个发送或接收操作后,才可访问该信息。
s.Bind(ipe);//绑定这个socket通信在这个连接点上。(对应的IP和端⼝) ,绑定了才能够通信和监听
////绑定EndPoint对像(2000端⼝和ip地址)
s.Listen(0);//将 Socket 置于侦听状态。
//Listen 可以让⼀个⾯向连接的 Socket 侦听传⼊的连接尝试。backlog 参数指定队列中最多可容纳的等待接受的传⼊连接数。
//可使⽤ Accept 或 BeginAccept 来接受来⾃队列的连接。
//在调⽤ Listen 之前,必须⾸先调⽤ Bind ⽅法,否则 Listen 将引发 SocketException。
//socket监听后,如果客户端开始连结,或请求发送数据。服务端怎么⽴即就知道有数据传送或连接请求啊--因为Listen
Console.Write("等待客户端请求,监听中");
//接受到client连接,为此连接建⽴新的socket,并接受信息
Socket temp = s.Accept();//为新建连接创建新的socket
//Accept 以同步⽅式从侦听套接字的连接请求队列中提取第⼀个挂起的连接请求,然后创建并返回新的 Socket。
/
/在阻⽌模式中,Accept 将⼀直处于阻⽌状态,直到传⼊的连接尝试排⼊队列。连接被接受后,原来的 Socket 继续将传⼊的连接请求排⼊队列,直到您关闭它。 //在调⽤ Accept ⽅法之前,必须⾸先调⽤ Listen ⽅法来侦听传⼊的连接请求,并将侦听到的请求放⼊队列中。
Console.Write("服务端建⽴连接……");
Console.Write("请按ENTER,接收客户端消息");
Console.ReadLine();
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//接收客户端数据即存⼊了Byte数组。⼜返回了长度。
//使⽤指定的 SocketFlags,从绑定的 Socket 接收指定字节数的数据,并将数据存⼊接收缓冲区。
/
/Byte 类型的数组,它是存储接收到的数据的位置、要接收的字节数。
//SocketFlags 值的按位组合。0表⽰不组合。
//返回数据长度
recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
//给client端返回信息
Console.Write("服务端得到消息 {0}", recvStr);//把客户端传来的信息显⽰出来
Console.Write("请按ENTER,发送收到信息给客户端");
Console.ReadLine();
String sendStr = "OK!Client Send message sucessful,Because Me Server received all.";
byte[] sendbytes = Encoding.ASCII.GetBytes(sendStr);
temp.Send(sendbytes, sendbytes.Length, 0);//Send() 将数据发送到连接的 Socket。
/
/因为这⾥是Socket编程。和TCPlisten编程有更⾼的封装。
Console.Write("对应客户端的服务要关闭,请按ENTER");
Console.ReadLine();
temp.Close();//虽然是对应的,可是服务端这⾥只要回复完了就⽴即关闭。不管对⽅怎么样..这⾥深刻说明了什么叫⽆状态。
s.Close();
Console.WriteLine();
}
}
}
客户端:
第⼀步:⽤指定的端⼝号和服务器的ip建⽴⼀个EndPoint对像;
第⼆步:建⽴⼀个Socket对像;
第三步:⽤socket对像的Connect()⽅法以上⾯建⽴的EndPoint对像做为参数,向服务器发出连接请求;
第四步:如果连接成功,就⽤socket对像的Send()⽅法向服务器发送信息;
第五步:⽤socket对像的Receive()⽅法接受服务器发来的信息 ;
socket通信在哪一层第六步:通信结束后⼀定记得关闭socket;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Client
{
class Program
{
static void Main(string [] args) {
int port = 2000;
string host = "127.0.0.1";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip,port);
Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Console.Write("客户端开始连接 ……");
c.Connect(ipe);
//如果当前使⽤的是⾯向连接的协议(如 TCP),则 Connect ⽅法会同步建⽴ LocalEndPoint 与指定远程终结点之间的⽹络连接。 //如果您使⽤的是⽆连接协议,Connect 会建⽴⼀个默认远程主机。
//在调⽤ Connect 之后,请使⽤ Send ⽅法将数据发送到远程设备,或者使⽤ Receive ⽅法从远程设备接收数据。
//如果您使⽤的是⽆连接协议(如 UDP),则不必先调⽤ Connect 即可发送和接收数据。
//您可以使⽤ SendTo 和 ReceiveFrom 来与远程主机进⾏同步通信。
//LocalEndPoint 属性获取⼀个包含 Socket 绑定到的本地 IP 地址和端⼝号的 EndPoint。
//您必须将此 EndPoint 强制转换为 IPEndPoint 才能检索信息。
//然后可以调⽤ IPEndPoint..::.Address ⽅法来检索该本地 IPAddress,调⽤ IPEndPoint..::.Port ⽅法来检索该本地端⼝号。
//LocalEndPoint 属性通常是在调⽤ Bind ⽅法之后设置的。
/
/如果允许系统分配套接字的本地 IP 地址和端⼝号,则将在第⼀次 I/O 操作之后设置 LocalEndPoint 属性。
//对于⾯向连接的协议⽽⾔,第⼀次 I/O 操作将是对 Connect 或 Accept ⽅法的调⽤。
//⽽对于⽆连接的协议⽽⾔,第⼀次 I/O 操作可以是任何发送或接收调⽤。
Console.Write("客户端连接成功,请按ENTER键,发送给服务器消息");
Console.ReadLine();
String sendStr="Hello!This is Client TalK!";
byte [] byteSend=Encoding.ASCII.GetBytes(sendStr);
Console.WriteLine("客户端发送消息");
c.Send(byteSend,byteSen
d.Length,0);
//从服务器端接受返回信息
byte[] reciveBytes = new byte[1024];
int recive;
recive = c.Receive(reciveBytes, reciveBytes.Length,0);
recvStr += Encoding.ASCII.GetString(reciveBytes, 0, recive);
Console.Write("客户端收到服务端发来信息:", recvStr);
Console.Write("客户端要关闭了。请按ENTER");
Console.ReadLine();
//这⾥的关闭也和服务器的没有怎么的关系。这⾥深刻说明了什么叫⽆状态。
c.Close();
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论