之前一直想自己搞把C#的Socket代碼,一直沒有下手,今晚終於實踐了一把。現把流程編寫出來,以備后用。
很簡單的源碼。
工具:Vs2010
建立項目:C# 控制台應用程序
Server代碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; //添加Socket類 using System.Net; using System.Net.Sockets; namespace SockeConsoleServer { 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並開始監聽 Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //創建一個Socket對象,如果用UDP協議,則要用SocketTyype.Dgram類型的套接字 s.Bind(ipe); //綁定EndPoint對象(2000端口和ip地址) s.Listen(0); //開始監聽 Console.WriteLine("等待客戶端連接"); //接受到Client連接,為此連接建立新的Socket,並接受消息 Socket temp = s.Accept(); //為新建立的連接創建新的Socket Console.WriteLine("建立連接"); string recvStr = ""; byte[] recvBytes = new byte[1024]; int bytes; bytes = temp.Receive(recvBytes,recvBytes.Length,0); //從客戶端接受消息 recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes); //給Client端返回信息 Console.WriteLine("server get message:{0}",recvStr); //把客戶端傳來的信息顯示出來 string sendStr = "ok!Client send message successful!"; byte[] bs = Encoding.ASCII.GetBytes(sendStr); temp.Send(bs,bs.Length,0); //返回信息給客戶端 temp.Close(); s.Close(); Console.ReadLine(); } } }
Client代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; //添加用於Socket的類 using System.Net; using System.Net.Sockets; namespace SocketConsoleClient { class Program { static void Main(string[] args) { try { int port = 2000; string host = "127.0.0.1"; //創建終結點EndPoint IPAddress ip = IPAddress.Parse(host); IPEndPoint ipe = new IPEndPoint(ip, port); //把ip和端口轉化為IPEndPoint的實例 //創建Socket並連接到服務器 Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 創建Socket Console.WriteLine("Connecting..."); c.Connect(ipe); //連接到服務器 //向服務器發送信息 string sendStr = "Hello,this is a socket test"; byte[] bs = Encoding.ASCII.GetBytes(sendStr); //把字符串編碼為字節 Console.WriteLine("Send message"); c.Send(bs, bs.Length, 0); //發送信息 //接受從服務器返回的信息 string recvStr = ""; byte[] recvBytes = new byte[1024]; int bytes; bytes = c.Receive(recvBytes, recvBytes.Length, 0); //從服務器端接受返回信息 recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes); Console.WriteLine("client get message:{0}", recvStr); //回顯服務器的返回信息 Console.ReadLine(); //一定記着用完Socket后要關閉 c.Close(); } catch (ArgumentException e) { Console.WriteLine("argumentNullException:{0}", e); } catch (SocketException e) { Console.WriteLine("SocketException:{0}",e); } } } }
代碼敲完之后,先跑下服務器,用netstat偵聽下端口的使用情況
服務器的運行界面(控制台界面)
運行客戶端(客戶端的控制台及服務器控制台界面顯示)
再用netstat偵聽下端口狀態
此時端口已連接正常,服務器已經與客戶端正常通信
附netstat使用說明:
顯示協議統計和當前 TCP/IP 網絡連接。
NETSTAT [-a] [-b] [-e] [-f] [-n] [-o] [-p proto] [-r] [-s] [-t] [interval]
-a 顯示所有連接和偵聽端口。
-b 顯示在創建每個連接或偵聽端口時涉及的可執行程序。
在某些情況下,已知可執行程序承載多個獨立的
組件,這些情況下,顯示創建連接或偵聽端口時涉
及的組件序列。此情況下,可執行程序的名稱
位於底部[]中,它調用的組件位於頂部,直至達
到 TCP/IP。注意,此選項可能很耗時,並且在您沒有
足夠權限時可能失敗。
-e 顯示以太網統計。此選項可以與 -s 選項結合使用。
-f 顯示外部地址的完全限定域名(FQDN)。
-n 以數字形式顯示地址和端口號。
-o 顯示擁有的與每個連接關聯的進程 ID。
-p proto 顯示 proto 指定的協議的連接;proto 可以是下列任
何一個: TCP、UDP、TCPv6 或 UDPv6。如果與 -s 選
項一起用來顯示每個協議的統計,proto 可以是下列任
何一個: IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP
或 UDPv6。
-r 顯示路由表。
-s 顯示每個協議的統計。默認情況下,顯示
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6
的統計;-p 選項可用於指定默認的子網。
-t 顯示當前連接卸載狀態。
interval 重新顯示選定的統計,各個顯示間暫停的間隔秒數。
按 CTRL+C 停止重新顯示統計。如果省略,則 netstat
將打印當前的配置信息一次。