C#基于Socket的網(wǎng)絡(luò)通信類你了解嗎
摘要
之所以要進(jìn)行Socket套接字通信庫(kù)封裝,主要是直接使用套接字進(jìn)行網(wǎng)絡(luò)通信編程相對(duì)復(fù)雜,特別對(duì)于初學(xué)者而言。實(shí)際上微軟從.net 2.0開始已經(jīng)提供了TCP、UDP通信高級(jí)封裝類如下:
TcpListener TcpClient UdpClient
微軟從.net 4.0開始提供基于Task任務(wù)的異步通信接口。而直接使用socket封裝庫(kù),很多socket本身的細(xì)節(jié)沒辦法自行控制,本文目就是提供一種socket的封裝供參考。文中展示部分封裝了TCP通信庫(kù),UDP封裝也可觸類旁通:
CusTcpListener CusTcpClient
代碼
using System;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace NetDemo
{
// 網(wǎng)絡(luò)操作相關(guān)的類
public class InternetProHelper
{
// 檢查設(shè)置的端口號(hào)是否正確,并返回正確的端口號(hào),無(wú)效端口號(hào)返回-1
public static int GetNetPort(string NetPort)
{
//聲明返回的正確端口號(hào)
int resPort = -1;
//檢測(cè)端口號(hào)
try
{
//傳入的端口號(hào)為空則拋出異常
if (NetPort == "")
{
throw new Exception("端口號(hào)不能為空!");
}
//檢測(cè)端口范圍
if ((Convert.ToInt32(NetPort) < ushort.MinValue) || (Convert.ToInt32(NetPort) > ushort.MaxValue))
{
throw new Exception("端口號(hào)范圍無(wú)效!");
}
//為端口號(hào)賦值
resPort = Convert.ToInt32(NetPort);
}
catch (Exception ex)
{
string errMessage = ex.Message;
}
return resPort;
}
public static IPAddress StringToIPAddress(string NetIP)
{
// 將字符串形式的IP地址轉(zhuǎn)換成IPAddress對(duì)象
return IPAddress.Parse(NetIP);
}
public static string LocalHostName
{
// 獲取本機(jī)的計(jì)算機(jī)名
get
{
return Dns.GetHostName();
}
}
public static string LANIP
{
// 獲取本機(jī)的局域網(wǎng)IP
get
{
//獲取本機(jī)的IP列表,IP列表中的第一項(xiàng)是局域網(wǎng)IP,第二項(xiàng)是廣域網(wǎng)IP
IPAddress[] IPaddrList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
//如果本機(jī)IP列表為空,則返回空字符串
if (IPaddrList.Length < 1)
{
return "";
}
//返回本機(jī)的局域網(wǎng)IP
return IPaddrList[0].ToString();
}
}
public static string GetClientIP(Socket clientSocket)
{
// 獲取遠(yuǎn)程客戶機(jī)的IP地址
IPEndPoint client = (IPEndPoint)clientSocket.RemoteEndPoint;//客戶端的NetSocket對(duì)象
return client.Address.ToString();
}
public static IPEndPoint CreateIPEndPoint(string NetIP, int NetPort)
{
// 創(chuàng)建一個(gè)IPEndPoint對(duì)象
IPAddress ipAddress = StringToIPAddress(NetIP);
return new IPEndPoint(ipAddress, NetPort);
}
public static TcpListener CreateTcpListener()
{
//創(chuàng)建一個(gè)自動(dòng)分配的網(wǎng)絡(luò)節(jié)點(diǎn)
IPAddress ipAddress = IPAddress.Any;
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 0);
return new TcpListener(localEndPoint);
}
public static TcpListener CreateTcpListener(string NetIP, int NetPort)
{
//創(chuàng)建一個(gè)網(wǎng)絡(luò)節(jié)點(diǎn)
IPAddress ipAddress = StringToIPAddress(NetIP);
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, NetPort);
return new TcpListener(localEndPoint);
}
public static Socket CreateTcpSocket()
{
// 創(chuàng)建一個(gè)基于TCP協(xié)議的Socket對(duì)象
return new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public static Socket CreateUdpSocket()
{
// 創(chuàng)建一個(gè)基于UDP協(xié)議的Socket對(duì)象
return new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
public static IPEndPoint GetLocalPoint(TcpListener tcpListener)
{
// 獲取TcpListener對(duì)象的本地終結(jié)點(diǎn)
return (IPEndPoint)tcpListener.LocalEndpoint;
}
public static string GetLocalPoint_IP(TcpListener tcpListener)
{
// 獲取TcpListener對(duì)象的本地終結(jié)點(diǎn)的IP地址
IPEndPoint localEndPoint = (IPEndPoint)tcpListener.LocalEndpoint;
return localEndPoint.Address.ToString();
}
public static int GetLocalPoint_Port(TcpListener tcpListener)
{
// 獲取TcpListener對(duì)象的本地終結(jié)點(diǎn)的端口號(hào)
IPEndPoint localEndPoint = (IPEndPoint)tcpListener.LocalEndpoint;
return localEndPoint.Port;
}
public static IPEndPoint GetLocalPoint(Socket NetSocket)
{
// 獲取Socket對(duì)象的本地終結(jié)點(diǎn)
return (IPEndPoint)NetSocket.LocalEndPoint;
}
public static string GetLocalPoint_IP(Socket NetSocket)
{
// 獲取Socket對(duì)象的本地終結(jié)點(diǎn)的IP地址
IPEndPoint localEndPoint = (IPEndPoint)NetSocket.LocalEndPoint;
return localEndPoint.Address.ToString();
}
public static int GetLocalPoint_Port(Socket NetSocket)
{
// 獲取Socket對(duì)象的本地終結(jié)點(diǎn)的端口號(hào)
IPEndPoint localEndPoint = (IPEndPoint)NetSocket.LocalEndPoint;
return localEndPoint.Port;
}
public static void BindEndPoint(Socket NetSocket, IPEndPoint endPoint)
{
// 綁定終結(jié)點(diǎn)
if (!NetSocket.IsBound)
{
NetSocket.Bind(endPoint);
}
}
public static void BindEndPoint(Socket NetSocket, string NetIP, int NetPort)
{
//創(chuàng)建終結(jié)點(diǎn)
IPEndPoint endPoint = CreateIPEndPoint(NetIP, NetPort);
//綁定終結(jié)點(diǎn)
if (!NetSocket.IsBound)
{
NetSocket.Bind(endPoint);
}
}
public static void StartListen(Socket NetSocket, int NetPort)
{
//創(chuàng)建本地終結(jié)點(diǎn)
IPEndPoint localPoint = CreateIPEndPoint(InternetProHelper.LocalHostName, NetPort);
//綁定到本地終結(jié)點(diǎn)
BindEndPoint(NetSocket, localPoint);
//開始監(jiān)聽
NetSocket.Listen(200);
}
public static void StartListen(Socket NetSocket, int NetPort, int maxConnection)
{
//創(chuàng)建本地終結(jié)點(diǎn)
IPEndPoint localPoint = CreateIPEndPoint(InternetProHelper.LocalHostName, NetPort);
//綁定到本地終結(jié)點(diǎn)
BindEndPoint(NetSocket, localPoint);
//開始監(jiān)聽
NetSocket.Listen(maxConnection);
}
public static void StartListen(Socket NetSocket, string NetIP, int NetPort, int maxConnection)
{
//綁定到本地終結(jié)點(diǎn)
BindEndPoint(NetSocket, NetIP, NetPort);
//開始監(jiān)聽
NetSocket.Listen(maxConnection);
}
public static bool Connect(Socket NetSocket, string NetIP, int NetPort)
{
// 連接到基于TCP協(xié)議的服務(wù)器,連接成功返回true,否則返回false
try
{
//連接服務(wù)器
NetSocket.Connect(NetIP, NetPort);
//檢測(cè)連接狀態(tài)
return NetSocket.Poll(-1, SelectMode.SelectWrite);
}
catch (SocketException ex)
{
throw new Exception(ex.Message);
}
}
// 以同步方式向指定的Socket對(duì)象發(fā)送消息
public static void SendMsg(Socket NetSocket, byte[] dataStr)
{
//發(fā)送消息
NetSocket.Send(dataStr, dataStr.Length, SocketFlags.None);
}
// 使用UTF8編碼格式以同步方式向指定的Socket對(duì)象發(fā)送消息
public static void SendMsg(Socket NetSocket, string dataStr)
{
//將字符串消息轉(zhuǎn)換成字符數(shù)組
byte[] NetBuf = System.Text.Encoding.UTF8.GetBytes(dataStr);
//發(fā)送消息
NetSocket.Send(NetBuf, NetBuf.Length, SocketFlags.None);
}
// 以同步方式接收消息
public static void ReceiveMsg(Socket NetSocket, byte[] NetBuf)
{
NetSocket.Receive(NetBuf);
}
// 以同步方式接收消息
public static string ReceiveMsg(Socket NetSocket)
{
//定義接收緩沖區(qū)
byte[] NetBuf = new byte[10000];
//接收數(shù)據(jù),獲取接收到的字節(jié)數(shù)
int RecvNum = NetSocket.Receive(NetBuf);
//定義臨時(shí)緩沖區(qū)
byte[] DataBuf = new byte[RecvNum];
//將接收到的數(shù)據(jù)寫入臨時(shí)緩沖區(qū)
Buffer.BlockCopy(NetBuf, 0, DataBuf, 0, RecvNum);
//對(duì)DataBuf進(jìn)行處理
return Convert.ToString(DataBuf);
}
// 關(guān)閉基于Tcp協(xié)議的Socket對(duì)象
public static void Close(Socket NetSocket)
{
try
{
//禁止Socket對(duì)象接收和發(fā)送數(shù)據(jù)
NetSocket.Shutdown(SocketShutdown.Both);
}
catch (SocketException ex)
{
throw ex;
}
finally
{
//關(guān)閉Socket對(duì)象
NetSocket.Close();
}
}
}
}總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C#與C++?dll之間傳遞字符串string?wchar_t*?char*?IntPtr問題
C#與C++?dll之間傳遞字符串string?wchar_t*?char*?IntPtr問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
Unity5.6大規(guī)模地形資源創(chuàng)建方法
這篇文章主要為大家詳細(xì)介紹了Unity5.6大規(guī)模地形資源創(chuàng)建方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
selenium.chrome寫擴(kuò)展攔截或轉(zhuǎn)發(fā)請(qǐng)求功能
Selenium?WebDriver?是一組開源?API,用于自動(dòng)測(cè)試?Web?應(yīng)用程序,利用它可以通過(guò)代碼來(lái)控制chrome瀏覽器,今天通過(guò)本文給大家介紹selenium?chrome寫擴(kuò)展攔截或轉(zhuǎn)發(fā)請(qǐng)求功能,感興趣的朋友一起看看吧2022-07-07

