using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace SocketTestApp
{
public partial class SocketTest : Form
{
//建立一個和客戶端通訊的套接字
Socket SocketWatch = null;
//定義一個集合,儲存客戶端資訊
Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, Socket> { };
public SocketTest()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//埠號(用來監聽的)
int port = 6000;
//string host = "127.0.0.1";
//IPAddress ip = IPAddress.Parse(host);
IPAddress ip = IPAddress.Any;
//將IP地址和埠號繫結到網路節點point上
IPEndPoint ipe = new IPEndPoint(ip, port);
//定義一個套接字用於監聽客戶端發來的訊息,包含三個引數(IP4定址協議,流式連線,Tcp協議)
SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//監聽繫結的網路節點
SocketWatch.Bind(ipe);
//將套接字的監聽佇列長度限制為20
SocketWatch.Listen(20);
//負責監聽客戶端的執行緒:建立一個監聽執行緒
Thread threadwatch = new Thread(ServerWatchConnecting);
//將窗體執行緒設定為與後臺同步,隨著主執行緒結束而結束
threadwatch.IsBackground = true;
//啟動執行緒
threadwatch.Start();
Console.WriteLine("開啟監聽......");
Console.WriteLine("點選輸入任意資料回車退出程式......");
richTextBox1.AppendText("開啟監聽......");
/*
Console.ReadKey();
SocketWatch.Close();
*/
}
//監聽客戶端發來的請求
void ServerWatchConnecting()
{
Socket connection = null;
//持續不斷監聽客戶端發來的請求
while (true)
{
try
{
connection = SocketWatch.Accept();
}
catch (Exception ex)
{
//提示套接字監聽異常
Console.WriteLine(ex.Message);
break;
}
//客戶端網路結點號
string remoteEndPoint = connection.RemoteEndPoint.ToString();
//新增客戶端資訊
ClientConnectionItems.Add(remoteEndPoint, connection);
string strTotalMsg = "\r\n[客戶端\"" + remoteEndPoint + "\"建立連線成功! 客戶端數量:" + ClientConnectionItems.Count + "]";
this.Invoke((MethodInvoker)delegate
{
lock (this.listBox1)
listBox1.Items.Add(remoteEndPoint);
});
//顯示與客戶端連線情況
Console.WriteLine(strTotalMsg);
//獲取客戶端的IP和埠號
IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
//讓客戶顯示"連線成功的"的資訊
string sendmsg = "[" + "本地IP:" + clientIP + " 本地埠:" + clientPort.ToString() + " 連線服務端成功!]";
byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
connection.Send(arrSendMsg);
this.Invoke((MethodInvoker)delegate
{
lock (this.richTextBox1)
this.richTextBox1.AppendText(strTotalMsg);
});
//建立一個通訊執行緒
Thread thread = new Thread(ServerRecv);
//啟動執行緒
thread.Start(connection);
}
}
void ServerRecv(object socket_obj)
{
Socket socketServer = socket_obj as Socket;
while (true)
{
//建立一個記憶體緩衝區,其大小為1024*1024位元組 即1M
byte[] arrServerRecMsg = new byte[1024 * 1024];
//將接收到的資訊存入到記憶體緩衝區,並返回其位元組陣列的長度
try
{
int length = socketServer.Receive(arrServerRecMsg);
if (length == 0)
continue;
//將機器接受到的位元組陣列轉換為人可以讀懂的字串
string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
string strTotalMsg = "\r\n[客戶端:" + socketServer.RemoteEndPoint + " 時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "]\r\n" + strSRecMsg;
this.Invoke((MethodInvoker)delegate
{
lock (this.richTextBox1)
this.richTextBox1.AppendText(strTotalMsg);
});
//將傳送的字串資訊附加到文字框txtMsg上
Console.WriteLine(strTotalMsg);
//Thread.Sleep(3000);
//socketServer.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:"+strSRecMsg));
//傳送客戶端資料
if (ClientConnectionItems.Count > 0)
{
foreach (var socketTemp in ClientConnectionItems)
{
socketTemp.Value.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:" + strSRecMsg));
}
}
}
catch (Exception)
{
listBox1.Items.Remove(socketServer.RemoteEndPoint.ToString());
ClientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString());
//提示套接字監聽異常
Console.WriteLine("\r\n[客戶端\"" + socketServer.RemoteEndPoint + "\"已經中斷連線! 客戶端數量:" + ClientConnectionItems.Count + "]");
//關閉之前accept出來的和客戶端進行通訊的套接字
socketServer.Close();
break;
}
}
}
private void button4_Click(object sender, EventArgs e)
{
if (ClientConnectionItems.Count > 0)
{
foreach (var socketTemp in ClientConnectionItems)
{
for(int cnt =0; cnt < listBox1.SelectedItems.Count; cnt++)
{
foreach (var item in listBox1.SelectedItems)
{
if (item.ToString() == socketTemp.Key)
{
socketTemp.Value.Send(Encoding.UTF8.GetBytes("[Msg from server]:" + textBox2.Text));
}
}
}
}
}
}
//建立1個客戶端套接字和1個負責監聽服務端請求的執行緒
Thread ThreadClient = null;
Socket SocketClient = null;
private void button2_Click(object sender, EventArgs e)
{
try
{
int port = 6000;
//string host = "127.0.0.1";//伺服器端ip地址
string host = textBox_target_ip.Text;
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
//定義一個套接字監聽
SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
//客戶端套接字連線到網路節點上,用的是Connect
SocketClient.Connect(ipe);
}
catch (Exception)
{
Console.WriteLine("連線失敗!\r\n");
Console.ReadLine();
return;
}
ThreadClient = new Thread(ClientRecv);
ThreadClient.IsBackground = true;
ThreadClient.Start();
Thread.Sleep(1000);
Console.WriteLine("請輸入內容<按Enter鍵傳送>:\r\n");
while (true)
{
string sendStr = Console.ReadLine();
ClientSendMsg(sendStr);
}
//int i = 1;
//while (true)
//{
// Console.Write("請輸入內容:");
// string sendStr = Console.ReadLine();
// Socket clientSocket = new Socket(AddressFamily.InterNetwork,ProtocolType.Tcp);
// clientSocket.Connect(ipe);
// //send message
// //byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr);
// byte[] sendBytes = Encoding.GetEncoding("utf-8").GetBytes(sendStr);
// //Thread.Sleep(4000);
// clientSocket.Send(sendBytes);
// //receive message
// string recStr = "";
// byte[] recBytes = new byte[4096];
// int bytes = clientSocket.Receive(recBytes,recBytes.Length,0);
// //recStr += Encoding.ASCII.GetString(recBytes,bytes);
// recStr += Encoding.GetEncoding("utf-8").GetString(recBytes,bytes);
// Console.WriteLine(recStr);
// clientSocket.Close();
// if (i >= 100)
// {
// break;
// }
// i++;
//}
//Console.ReadLine();
//return;
//string result = String.Empty;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
//接收服務端發來資訊的方法
public void ClientRecv()
{
int x = 0;
//持續監聽服務端發來的訊息
while (true)
{
try
{
//定義一個1M的記憶體緩衝區,用於臨時性儲存接收到的訊息
byte[] arrRecvmsg = new byte[1024 * 1024];
//將客戶端套接字接收到的資料存入記憶體緩衝區,並獲取長度
int length = SocketClient.Receive(arrRecvmsg);
//將套接字獲取到的字元陣列轉換為人可以看懂的字串
string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
if (x == 1)
{
string strTotalMsg = "\r\n伺服器:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "\r\n" + strRevMsg + "\r\n";
Console.WriteLine(strTotalMsg);
this.Invoke((MethodInvoker)delegate
{
lock (this.richTextBox2)
this.richTextBox2.AppendText(strTotalMsg);
});
}
else
{
string strTotalMsg = strRevMsg + "\r\n";
Console.WriteLine(strTotalMsg);
this.Invoke((MethodInvoker)delegate
{
lock (this.richTextBox2)
this.richTextBox2.AppendText(strTotalMsg);
});
x = 1;
}
}
catch (Exception ex)
{
Console.WriteLine("遠端伺服器已經中斷連線!" + ex.Message + "\r\n");
break;
}
}
}
//傳送字元資訊到服務端的方法
public void ClientSendMsg(string sendMsg)
{
//將輸入的內容字串轉換為機器可以識別的位元組陣列
byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
//呼叫客戶端套接字傳送位元組陣列
SocketClient.Send(arrClientSendMsg);
}
private void button3_Click(object sender, EventArgs e)
{
ClientSendMsg(textBox1.Text);
}
}
}