基于Tcp協定的Socket通訊類似于B/S架構,面向連接配接,但不同的是伺服器端可以向用戶端主動推送消息。
使用Tcp協定通訊需要具備以下幾個條件:
(1).建立一個套接字(Socket)
(2).綁定伺服器端IP位址及端口号--伺服器端
(3).利用Listen()方法開啟監聽--伺服器端
(4).利用Accept()方法嘗試與用戶端建立一個連接配接--伺服器端
(5).利用Connect()方法與伺服器建立連接配接--用戶端
(5).利用Send()方法向建立連接配接的主機發送消息
(6).利用Recive()方法接受來自建立連接配接的主機的消息(可靠連接配接)
以下為個人平時編寫的執行個體
TCP服務端執行個體
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
namespace TcpServerConsoleApp
{
class Program
{
/// <summary>
/// 伺服器端的監聽器
/// </summary>
private static TcpListener _tcpl = null;
/// <summary>
/// 本機IP位址
/// </summary>
private static IPAddress _ip = null;
private static int _port = 9005;
static void Main(string[] args)
{
GetLocationIp();//擷取IP位址
StartTcpServer();//啟動
}
private static void GetLocationIp()
{
//IP4擷取IP位址
//IPAddress _ip = Dns.GetHostAddresses(Dns.GetHostName())[0];//可能有多個,此時的IP是本地IP
//如果在IP6的需要以下發送擷取IP位址
IPHostEntry IpEntry = Dns.GetHostEntry(Dns.GetHostName());
for (int i = 0; i < IpEntry.AddressList.Length; i++)
{
//從IP位址清單中篩選出IPv4類型的IP位址
//AddressFamily.InterNetwork表示此IP為IPv4,
//AddressFamily.InterNetworkV6表示此位址為IPv6類型
if (IpEntry.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
_ip = IpEntry.AddressList[i];
break;
}
}
}
/// <summary>
/// 啟動TCP伺服器
/// </summary>
/// <param name="port"></param>
private static void StartTcpServer()
{
try
{
_tcpl = new TcpListener(_ip, _port);
_tcpl.Start();
Console.WriteLine("伺服器已啟動,正在監聽...
");
Console.WriteLine(string.Format("伺服器IP:{0} 端口号:{1}
", _ip, _port));
//AcceptSocket 是一個阻止方法,該方法傳回可用于發送和接收資料的 Socket。
//如果希望避免阻止,請使用 Pending 方法來确定傳入連接配接隊列中的連接配接請求是否可用。
//傳回的 Socket 是使用遠端主機的 IP 位址和端口号初始化的。
//您可以使用 Socket 類中任何可用的 Send 和 Receive 方法與遠端主機進行通信。
//------------使用 Socket 後,請確定調用其 Close 方法。如果應用程式相對簡單,-----------
//請考慮使用 AcceptTcpClient 方法代替 AcceptSocket 方法。
//TcpClient 提供了一些通過網絡在阻止同步模式下發送和接收資料的簡單方法。
Socket newClient = _tcpl.AcceptSocket();//本地TcpListener 接受新的請求
//傳回的 Socket 是使用遠端主機的 IP 位址和端口号初始化的
//byte[] packetBuff = new byte[10 * 1024];//接收資料緩沖區大小10K
//newClient.Receive(packetBuff);
Console.WriteLine("接入客服端:{0}", newClient.RemoteEndPoint.ToString());
Thread clientThread = new Thread(() => ThrendReciveFunc(newClient));
clientThread.Start();
}
catch
{ }
}
/// <summary>
/// 接收子線程
/// </summary>
/// <param name="socketClient"></param>
private static void ThrendReciveFunc(Socket socketClient)
{
while (true)
{
try
{
byte[] buffer = new byte[10 * 1024];//接收資料緩沖區
int count = socketClient.Receive(buffer);
string msg = Encoding.Default.GetString(buffer, 0, count);
Console.WriteLine("收到消息:{0}", msg);
string sendmsg = "收到消息!";
socketClient.Send(Encoding.Default.GetBytes(sendmsg));
}
catch (Exception ex)
{
Console.WriteLine(string.Format("出現異常:{0}", ex.Message));
Thread.CurrentThread.Abort();//結束該接收線程
Console.Read();
break;
}
}
}
}
}
TCP客服端執行個體
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace TcpClientConsolApp
{
class Program
{
static IPAddress _ip = null;
static TcpClient _tcpc;
static NetworkStream Netstream;//提供用于通路網絡的基本資料流
static void Main(string[] args)
{
Console.WriteLine("請輸入IP位址:");
GetIpAddr();
Console.WriteLine("請輸入端口号:");
int port = Convert.ToInt16(Console.ReadLine());
try
{
_tcpc = new TcpClient();
_tcpc.Connect(_ip, port);
if (_tcpc != null)
{
Console.WriteLine("連接配接成功");
Netstream = _tcpc.GetStream();
Thread recvieThread = new Thread(RecvieFunc);
recvieThread.Start();
/*發送資料*/
while (true)
{
Console.WriteLine("輸入要發送的資料");
byte[] msg = Encoding.Default.GetBytes(Console.ReadLine());
Netstream.Write(msg, 0, msg.Length);
}
}
else
{
Console.WriteLine("連接配接失敗!");
}
}
catch
{ }
Console.Read();
}
static void GetIpAddr()
{
try
{
_ip = IPAddress.Parse(Console.ReadLine());
}
catch
{
}
if (_ip == null)
{
Console.WriteLine("輸入IP位址有誤,請重新輸入");
GetIpAddr();
}
}
/// <summary>
/// 接收線程
/// </summary>
static void RecvieFunc()
{
while (_tcpc.Client.Connected)
{
try
{
byte[] buffer = new byte[10 * 1024];
int count = _tcpc.Client.Receive(buffer);
string msg = Encoding.Default.GetString(buffer, 0, count);
Console.WriteLine("接收到資訊:{0}", msg);
}
catch (Exception ex)
{
Console.WriteLine(string.Format("出現異常:{0}", ex.Message));
//Netstream = null;
Netstream.Close();
Thread.CurrentThread.Abort();
break;
}
}
}
}
}