一、socket简介
socket就是套接字,它是引用网络连接的特殊文件描述符,由三个基本要素组成:
1: AddressFamily(网络类型)
2: SocketType(数据传输类型)
3:ProtocolType(采用的网络协议)
下面是可用于IP通信的套接字组合及其常用的属性和方法
二、socket与网络通信
IP连接领域有两种通信类型:面向连接的和无连接的,这里我要讲的是面向连接的,使用TCP协议来建立两个IP的值端点之间的会话,下面是它的基本步骤。
a:建立一个套接字
b:绑定本机的IP和端口
c:使用listen()方法监听别人发过来的东西
d:如果监听到连接,则可以使用Send/Receive来执行操作
e:完成后使用Close()方法进行关闭
工作原理如图所示:
三、一个简单的同步通信示例
1.服务器端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.Threading; namespace socket服务端 { class Program { static void Main( string [] args) { int port = 23456; //端口号 int recv; //记录客户端信息的长度 string address = "127.0.0.1" ; //IP地址,指向localhost主机名,常用于程序调试 IPAddress addr = IPAddress.Parse(address); IPEndPoint ipe = new IPEndPoint(addr, port); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(ipe); //绑定端口 socket.Listen(0); //开始监听,0表示任意数量 Console.WriteLine( "已启动监听,等待客户端连接。" ); Socket clientSocket = socket.Accept(); IPEndPoint clientIp = (IPEndPoint)clientSocket.RemoteEndPoint; //获取远程终结点信息 if (clientSocket != null ) Console.WriteLine( "成功与{0}的客户端建立联系" ,clientIp); while ( true ) //用死循环不断执行 { try { byte [] data = new byte [1024]; recv = clientSocket.Receive(data); //获取客户端传过来的信息 if (recv == 0) break ; Console.WriteLine( "客户端发来信息:{0}" ,Encoding.ASCII.GetString(data, 0, recv)); Console.Write( "输入要发送的信息:" ); String input = Console.ReadLine(); clientSocket.Send(Encoding.ASCII.GetBytes(input)); } catch (Exception ex) { Console.WriteLine( "ERROR:{0}" , ex.Message); } } Console.WriteLine( "断开连接" ); clientSocket.Close(); socket.Close(); } } } |
2.客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; namespace socket客户端 { class Program { static void Main( string [] args) { int port = 23456; string address = "127.0.0.1" ; byte [] data = new byte [1024]; IPAddress addr = IPAddress.Parse(address); IPEndPoint ipe = new IPEndPoint(addr, port); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(ipe); Console.WriteLine( "与服务器连接成功" ); try { while ( true ) { Console.Write( "输入信息内容:" ); string input = Console.ReadLine(); if (input == "exit" ) break ; socket.Send(Encoding.ASCII.GetBytes(input)); //发送数据 data = new byte [1024]; int recv; string strData; recv = socket.Receive(data); strData = Encoding.ASCII.GetString(data, 0, recv); Console.WriteLine( "服务器发来内容:{0}" ,strData); } } catch (SocketException ex) { Console.WriteLine(ex.ToString()); } Console.WriteLine( "断开连接..." ); socket.Shutdown(SocketShutdown.Both); socket.Close(); Console.ReadKey(); } } } |
接下来对上面一些内容进行解释
a.端口号:32位无符号整形,范围是0~65535,0~1023被系统进程和通信协议使用,1024~49251是用户可以使用的端口
b.IPAddress类: 该类有一个Parse()方法,可以把点分的十进制IP转化为IPAdress类, 它还有四个可读字段
Any:用于代表本地系统可用的任何IP地址
Broadcase:用于代表本地网络的IP广播地址
Loopback:用于代表本地系统的回送地址
None:用于代表本地系统上没有网络接口
c.IPEndPoint是一个端口和IP地址的绑定,可以代表一个服务,用来Socket通信,可以通过两种方法构造
IPEndPoint( long address, int pot);
IPEndPoint( IPAddress address, int pot)'
d. Accept 以同步方式从侦听套接字,在连接请求队列中提取第一个挂起的连接请求,然后创建并返回一个新Socket。 不能使用此返回Socket为接受任何其他连接的连接队列。 但是,可以调用RemoteEndPoint方法所返回的Socket来标识远程主机的网络地址和端口号。
e.Receive()从绑定的 Socket套接字接收数据,将数据存入接收缓冲区。
注:同步通信每发完一个数据包后,需要等待接收方响应后再继续发送下一个数据包
运行时先启动服务器端,再启动客户端