C# Socket收集編程實例。本站提示廣大學習愛好者:(C# Socket收集編程實例)文章只能為提供參考,不一定能成為您想要的結果。以下是C# Socket收集編程實例正文
本文實例講述了C# Socket收集編程技能。分享給年夜家供年夜家參考。詳細剖析以下:
客戶端要銜接辦事器:起首要曉得辦事器的IP地址。而辦事器裡有許多的運用法式,每個運用法式對應一個端標語
所以客戶端想要與辦事器中的某個運用法式停止通訊就必需要曉得誰人運用法式的地點辦事器的IP地址,及運用法式所對應的端標語
TCP協定:平安穩固,普通不會產生數據喪失,然則效力低。應用TCP產生數據普通經由3次握手(一切效力低,本身百度三次握手)
UDP協定:疾速,效力高,然則不穩固,輕易產生數據喪失(沒有經由三次握手,不論辦事器有空沒空,信息全往辦事器發,一切效力弄,但辦事器忙的時刻就沒方法處置你的數據,輕易形成數據喪失,不穩固)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace Socket通訊
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.txtPort.Text = "5000";
this.txtIp.Text = "192.168.137.1";
}
private void btnStart_Click(object sender, EventArgs e)
{
//當點擊開端監聽的時刻,在辦事器端創立一個擔任監聽IP地址跟端標語的Socket
Socket socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//Any:供給一個 IP 地址,指導辦事器應偵聽一切收集接口上的客戶端運動。此字段為只讀。
IPAddress ip = IPAddress.Any;
//創立端標語對象;將txtPort.Text控件的值設為辦事真個端標語
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
//監聽
socketWatch.Bind(point);
ShowMsg("監聽勝利");
socketWatch.Listen(10);//銜接隊列的最年夜長度 ;即:一個時光點內最年夜能讓幾個客戶端銜接出去,跨越長度就停止列隊
//期待客戶端銜接;Accept()這個辦法能吸收客戶真個銜接,並為新銜接創立一個擔任通訊的Socket
Thread th = new Thread(Listen); //被線程履行的辦法假如有參數的話,參數必需是object類型
Control.CheckForIllegalCrossThreadCalls = false; //由於.net不許可跨線程拜訪的,所以這裡撤消跨線程的檢討。.net不檢討能否有跨線程拜訪了,一切就不會報: “從不是創立控件“txtLog”的線程拜訪它” 這個毛病了,從而完成了跨線程拜訪
th.IsBackground = true; //將th這個線程設為後台線程。
//Start(object parameter); parameter:一個對象,包括線程履行的辦法要應用的數據,即線程履行Listen辦法,Listen的參數
th.Start(socketWatch); //這個括號裡的參數實際上是Listen()辦法的參數。由於Thread th = new Thread(Listen)這個括號裡只能寫辦法名(函數名) 然則Listen()辦法是有參數的,一切就要用Start()辦法將它的參數添加出去
}
/// <summary>
/// 期待客戶端銜接,假如監控到有客戶端銜接出去就創立一個與之通訊的Socket
/// </summary>
/// <param name="o"></param>
void Listen(object o) //這裡為何不直接傳遞Socket類型的參數呢? 緣由是:被線程履行的辦法假如有參數的話,參數必需是object類型
{
Socket socketWatch = o as Socket;
while (true) //為何這裡要有個while輪回?由於當一小我銜接出去的時刻創立了與之通訊的Socket後就法式就會往下履行了,就不會再回來為第二小我的銜接創立擔任通訊的Socket了。(應當是每一個人(每一個客戶端)創立一個與之通訊的Socket)所以要寫在輪回裡。
{
//期待客戶端銜接;Accept()這個辦法能吸收客戶真個銜接,並為新銜接創立一個擔任通訊的Socket
Socket socketSend = socketWatch.Accept();
dic.Add(socketSend.RemoteEndPoint.ToString(), socketSend); //(依據客戶真個IP地址和端標語找擔任通訊的Socket,每一個客戶端對應一個擔任通訊的Socket),ip地址及端標語作為鍵,將擔任通訊的Socket作為值填充到dic鍵值對中。
//我們經由過程擔任通訊的這個socketSend對象的一個RemoteEndPoint屬性,可以或許拿到長途連過去的客戶真個Ip地址跟端標語
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "銜接勝利");//後果:192.168.1.32:銜接勝利
comboBox1.Items.Add(socketSend.RemoteEndPoint.ToString()); //將銜接過去的每一個客戶端都添加到combBox控件中。
//客戶端銜接勝利後,辦事器應當吸收客戶端發來的新聞。
Thread getdata = new Thread(GetData);
getdata.IsBackground = true;
getdata.Start(socketSend);
}
}
Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
/// <summary>
/// 一直的吸收客戶端發送過去的新聞
/// </summary>
/// <param name="o"></param>
void GetData(object o)
{
while (true)
{
Socket socketSend = o as Socket;
//將客戶端發過去的數據先放到一個字節數組外面去
byte[] buffer = new byte[1024 * 1024 * 2]; //創立一個字節數組,字節數組的長度為2M
//現實吸收到的有用字節數; (應用Receive辦法吸收客戶端傳過去的數據,然後把數據保留到buffer字節數組中,前往一個吸收到的數據的長度)
int r = socketSend.Receive(buffer);
if (r == 0) //假如吸收到的有用字節數為0 解釋客戶端曾經封閉了。這時候候就跳出輪回了。
{
//只要客戶端給用戶發新聞,弗成能是發0個長度的字節。即使發空新聞,空新聞也是有過個長度的。一切吸收到的有用字節長度為0就代表客戶端曾經封閉了
break;
}
//將buffer這個字節數組外面的數據依照UTF8的編碼,解碼成我們可以或許讀懂的的string類型,由於buffer這個數組的現實存儲數據的長度是r個 ,所以從索引為0的字節開端解碼,總共解碼r個字節長度。
string str = Encoding.UTF8.GetString(buffer, 0, r);
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + str);
}
}
private void ShowMsg(string str)
{
txtLog.AppendText(str + "\r\n"); //將str這個字符串添加到txtLog這個文本框中。
}
/// <summary>
/// 辦事端給客戶端發信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click_1(object sender, EventArgs e)
{
if (comboBox1.SelectedItem == null) //假如comboBox控件沒有選中值。就提醒用戶選擇客戶端
{
MessageBox.Show("請選擇客戶端");
return;
}
string str = txtMes.Text; //獲得用戶輸出的內容 (辦事端要給客戶端發的信息)
byte[] strByte = Encoding.Default.GetBytes(str); //將信息轉換成二進制字節數組
string getIp = comboBox1.SelectedItem as string; //comboBox存儲的是客戶真個(ip+端標語)
Socket socketSend = dic[getIp] as Socket; //依據這個(ip及端標語)去dic鍵值對中找對應 賦值與客戶端通訊的Socket【每一個客戶端都有一個擔任與之通訊的Socket】
socketSend.Send(strByte); //將信息發送到客戶端
}
}
}
開翻開始敕令 cmd telnet 10.18.16.46 5000 即telnet 辦事器ip地址 綁定的端標語
願望本文所述對年夜家的C#法式設計有所贊助。