日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# Socket编程实现简单的局域网聊天器

發布時間:2024/1/1 C# 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# Socket编程实现简单的局域网聊天器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言
最近在學習C# Socket相關的知識,學習之余,動手做了一個簡單的局域網聊天器。有萌生做這個的想法,主要是由于之前家里兩臺電腦之間想要傳輸文件十分麻煩,需要借助QQ,微信或者其他第三方應用,基本都要登錄,而且可能傳輸的文件還有大小限制,壓縮問題。所以本聊天器的首要目標就是解決這兩個問題,做到使用方便(雙擊啟動即用),傳文件無限制。
廢話不多說,先上圖。S-Chat是服務端,C-Chat是客戶端,兩者除了客戶端首次啟動后需要設置一下連接的IP地址外,無其他區別。操作與界面都完全相同,對于用戶來說,基本不用在意誰是服務端誰是客戶端。

編碼
服務端監聽接口
服務端主要負責開啟監聽線程,等待客戶端接入

public void StartListen() {// 創建Socket對象 new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)Socket socket = GetSocket();// 將套接字與IPEndPoint綁定socket.Bind(this.GetIPEndPoint());// 開啟監聽 僅支持一個連接socket.Listen(1);// 開啟線程等待客戶端接入,避免堵塞Thread acceptThread = new Thread(new ThreadStart(TryAccept));acceptThread.IsBackground = true;acceptThread.Start(); }public void TryAccept() {Socket socket = GetSocket();while (true){try{Socket connectedSocket = socket.Accept()this.ConnectedSocket = connectedSocket;OnConnect(); // 連接成功回調this.StartReceive(); // 開始接收線程break;}catch (Exception e){}} }

客戶端連接接口
客戶端主要負責開啟連接線程,每隔2秒,自動嘗試連接服務端

public void StartConnect() {Thread connectThread = new Thread(new ThreadStart(TryConnect));connectThread.IsBackground = true;connectThread.Start(); }public void TryConnect() {Socket socket = GetSocket();while (true){try{socket.Connect(this.GetIPEndPoint());this.ConnectedSocket = socket;OnConnect(); // 連接成功回調this.StartReceive();break;}catch (Exception e){Thread.Sleep(TryConnectInterval); // 指定間隔后重新嘗試連接}} }

文字發送,文件發送,接收文字,接收文件等通用接口主要實現在ChatBase類中,是服務端與客戶端的共同父類。

文字發送接口
發送數據的第一位表示發送信息的類型,0表示字符串文字,1表示文件
然后獲取待發送字符串的長度,使用long類型表示,占用8個字節
共發送的字節數據可以表示為頭部(類型 + 字符串字節長度,共9個字節)+ 實際字符串字節數據

public bool Send(string msg) {if (ConnectedSocket != null && ConnectedSocket.Connected){byte[] buffer = UTF8.GetBytes(msg); byte[] len = BitConverter.GetBytes((long)buffer.Length); byte[] content = new byte[1 + len.Length + buffer.Length]; content[0] = (byte)ChatType.Str; // 發送信息類型,字符串Array.Copy(len, 0, content, 1, len.Length); // 字符串字節長度Array.Copy(buffer, 0, content, 1 + len.Length, buffer.Length); // 實際字符串字節數據try{ConnectedSocket.Send(content);return true;}catch (Exception e){}}return false; }

文件發送接口
與字符串發送相同的頭部可以表示為(類型 + 文件長度,共9個字節)
還需要再加上待發送的文件名的長度,與文件名字節數據
共發送的字節數據可以表示為頭部(類型 + 文件長度,共9個字節)+ 文件名頭部(文件名長度 + 文件名字節數據)+ 實際文件數據

public bool SendFile(string path) {if (ConnectedSocket != null && ConnectedSocket.Connected){try{FileInfo fi = new FileInfo(path);byte[] len = BitConverter.GetBytes(fi.Length); byte[] name = UTF8.GetBytes(fi.Name); byte[] nameLen = BitConverter.GetBytes(name.Length); byte[] head = new byte[1 + len.Length + nameLen.Length + name.Length];head[0] = (byte)ChatType.File; // 加上信息發送類型Array.Copy(len, 0, head, 1, len.Length); // 加上文件長度Array.Copy(nameLen, 0, head, 1 + len.Length, nameLen.Length); // 加上文件名長度Array.Copy(name, 0, head, 1 + len.Length + nameLen.Length, name.Length); // 加上文件名字節數據ConnectedSocket.SendFile(path,head,null,TransmitFileOptions.UseDefaultWorkerThread);return true;}catch(Exception e){}}return false; }

信息接收接口(文字與文件)
主要是解析接收到的字節數據,根據字符串或文件的類型進行處理

public void Receive() {if (ConnectedSocket != null){while (true){try{// 讀取公共頭部byte[] head = new byte[9];ConnectedSocket.Receive(head, head.Length, SocketFlags.None);int len = BitConverter.ToInt32(head, 1);if (head[0] == (byte) ChatType.Str){// 接收字符串byte[] buffer = new byte[len];ConnectedSocket.Receive(buffer, len, SocketFlags.None);OnReceive(ChatType.Str, UTF8.GetString(buffer));}else if(head[0] == (byte)ChatType.File){// 接收文件if (!Directory.Exists(dirName)){Directory.CreateDirectory(dirName);}// 讀取文件名信息byte[] nameLen = new byte[4];ConnectedSocket.Receive(nameLen, nameLen.Length, SocketFlags.None);byte[] name = new byte[BitConverter.ToInt32(nameLen, 0)];ConnectedSocket.Receive(name, name.Length, SocketFlags.None);string fileName = UTF8.GetString(name);// 讀取文件內容并寫入int readByte = 0;int count = 0;byte[] buffer = new byte[1024 * 8];string filePath = Path.Combine(dirName, fileName);if (File.Exists(filePath)){File.Delete(filePath);}using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write)){while (count != len){int readLength = buffer.Length;if(len - count < readLength){readLength = len - count;}readByte = ConnectedSocket.Receive(buffer, readLength, SocketFlags.None);fs.Write(buffer, 0, readByte);count += readByte;}}OnReceive(ChatType.File, fileName); }else{// 未知類型}}catch (Exception e){}}} }

使用
第一次vb.net教程使用,客戶java基礎端需要python基礎教程設置待連接的IP地址。之后再啟動會自動連接

雙擊服務端exe啟動,點擊設置,查看IP地址項

雙擊客戶端exe啟動,點擊設置,在IP地址項,輸入服務端查看到的IP地址

設置成功后,等待大約一兩秒,應用c#教程cion變成綠色,即表示連接成功,可以正常發送sql語句文字和文件了

可以點擊選擇文件(支持選擇多個文件),發送文件

支持直接拖拽文件到輸入框,發送文件

支持Ctrl+Enter快捷鍵發送

接收到的文件自動存放在exe所在目錄的ChatFiles文件夾下

注意事項
客戶端服務端需要在同一個局域網下才能實現連接
服務端IP地址是不支持修改的,自動讀取本機的IP地址
源碼
完整代碼放在GitHub上,點擊查看
預編譯好的可運行exe程序,在倉庫的Release目錄,也可以直接通過百度云下載,提取碼v4pe
作者:iwiniwin
出處:http://www.cnblogs.com/iwiniwin/

總結

以上是生活随笔為你收集整理的C# Socket编程实现简单的局域网聊天器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。