本文主要结构为:【1】Socket概述【2】Socket实现步骤【3】Socket常用方法【4】实现代码和运行结果【5】参考说明
【1】Socket概述
1. Microsoft.Net Framework为应用程序访问Internet提供了分层的、可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的类可以开发多种网络应用程序。System.Net.Sockets 命名空间,里面包含了Socket类。.
2. Windows中的很多东西都是从Unix领域借鉴过来的,Socket也是一样。在Unix中,socket代表了一种文件描述符(在Unix中一切都是以文件为单位),而这里这个描述符则是用于描述网络访问的。可以通过socket来发送和接收网络上的数据。你也可以理解成是一个API。有了它,你就不用直接去操作网卡了,而是通过这个接口,这样就省了很多复杂的操作。
3. 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
4. 抛开ISO/OSI模型的7层构架,单从TCP/IP模型上的逻辑层面上看,.Net类可以视为包含3个层次:请求/响应层、应用协议层、传输层。WebReqeust和WebResponse 代表了请求/响应层,支持Http、Tcp和Udp的类组成了应用协议层,而Socket类处于传输层。
【2】Socket实现步骤 a. 建立一个套接字 b. 绑定本机的IP和端口 c. 如果是TCP,因为是面向连接的,所以要利用ListenO()方法来监听网络上是否有人给自己发东西;如果是UDP,因为是无连接的,所以来者不拒。 d. TCP情况下,如果监听到一个连接,就可以使用accept来接收这个连接,然后就可以利用Send/Receive来执行操作了。而UDP,则不需要accept, 直接使用SendTo/ReceiveFrom来执行操作。(看清楚哦,和TCP的执行方法有区别,因为UDP不需要建立连接,所以在发送前并不知道对方的IP和端口,因此需要指定一个发送的节点才能进行正常的发送和接收) e. 如果你不想继续发送和接收了,就不要浪费资源了。能close的就close吧。 如果看了上面文字,你还不清楚的话,就来看看图好了:
面向连接的套接字系统调用时序
无连接的套接字系统调用时序
【3】Socket常用方法
Socket.Connect方法:建立到远程设备的连接
public void Connect(EndPoint remoteEP)(有重载方法)
Socket.Send 方法:从数据中的指示位置开始将数据发送到连接的 Socket。
public int Send(byte[], int, SocketFlags);(有重载方法)
Socket.SendTo 方法 将数据发送到特定终结点。
public int SendTo(byte[], EndPoint);(有重载方法)
Socket.Receive方法:将数据从连接的 Socket 接收到接收缓冲区的特定位置。
public int Receive(byte[],int,SocketFlags);
Socket.ReceiveFrom方法:接收数据缓冲区中特定位置的数据并存储终结点。
public int ReceiveFrom(byte[], int, SocketFlags, ref EndPoint);
Socket.Bind 方法:使 Socket 与一个本地终结点相关联:
public void Bind( EndPoint localEP );
Socket.Listen方法:将 Socket 置于侦听状态。
public void Listen( int backlog );
Socket.Accept方法:创建新的 Socket 以处理传入的连接请求。
public Socket Accept();
Socket.Shutdown方法:禁用某 Socket 上的发送和接收
public void Shutdown( SocketShutdown how );
Socket.Close方法:强制 Socket 连接关闭
public void Close();
【4】实现代码和运行结果(TCP为例)
1.Socket服务器
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; //添加引用 using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace SocketServer { public partial class Form1 : Form { Thread mythread;//创建线程 Socket socket; int port = 8000;//定义侦听端口号 public Form1() { InitializeComponent(); } //获取本机IP地址 public static IPAddress GetServerIP() { IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName()); return ieh.AddressList[0]; } //监听 private void BeginListen() { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ServerIp = GetServerIP(); IPEndPoint iep = new IPEndPoint(ServerIp, port); socket.Bind(iep); toolStripStatusLabel1.Text = iep.ToString() + "正在监听..."; byte[] byteMessage = new byte[100]; while (true) { try { socket.Listen(5); Socket newSocket = socket.Accept(); newSocket.Receive(byteMessage); string sTime = DateTime.Now.ToShortTimeString(); string msg = sTime + "-" + "信息来自:"; msg += newSocket.RemoteEndPoint.ToString() +" "+ Encoding.Default.GetString(byteMessage).Trim(new char[] {'/0'}); richTextBox1.AppendText(msg + "/r/n"); } catch (SocketException ex) { toolStripStatusLabel1.Text += ex.ToString(); } } } private void btn_Listen_Click(object sender, EventArgs e) { try { mythread = new Thread(new ThreadStart(BeginListen)); mythread.Start(); } catch (System.Exception er) { MessageBox.Show(er.Message, "完成", MessageBoxButtons.OK, MessageBoxIcon.Stop); } } } }
2.Socket客户端
using System; using System.Windows.Forms; //添加引用 using System.Net; using System.Net.Sockets; using System.Text; namespace SocketClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //得到本机地址 IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName()); txtIP.Text = ieh.AddressList[0].ToString(); } private void btn_Send_Click(object sender, EventArgs e) { BeginSend(); } //发送信息 private void BeginSend() { string ip = txtIP.Text; string port = txtPort.Text; string msg = txtMsg.Text.Trim(); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress serverIp = IPAddress.Parse(ip); int serverPort = Convert.ToInt32(port); IPEndPoint iep = new IPEndPoint(serverIp, serverPort); socket.Connect(iep); byte[] byteMessage; byteMessage = Encoding.ASCII.GetBytes(msg); socket.Send(byteMessage); socket.Shutdown(SocketShutdown.Both); socket.Close(); } } }
【5】参考说明
1. http://www.cnblogs.com/stg609/archive/2008/11/15/1333889.html
2. http://blog.csdn.net/JavaProgramers/archive/2008/02/20/2108460.aspx