C#TCP实现多个客户端与服务端数据与文件的传输.docx

上传人:scccc 文档编号:12544235 上传时间:2021-12-04 格式:DOCX 页数:27 大小:107.23KB
返回 下载 相关 举报
C#TCP实现多个客户端与服务端数据与文件的传输.docx_第1页
第1页 / 共27页
C#TCP实现多个客户端与服务端数据与文件的传输.docx_第2页
第2页 / 共27页
C#TCP实现多个客户端与服务端数据与文件的传输.docx_第3页
第3页 / 共27页
C#TCP实现多个客户端与服务端数据与文件的传输.docx_第4页
第4页 / 共27页
C#TCP实现多个客户端与服务端数据与文件的传输.docx_第5页
第5页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《C#TCP实现多个客户端与服务端数据与文件的传输.docx》由会员分享,可在线阅读,更多相关《C#TCP实现多个客户端与服务端数据与文件的传输.docx(27页珍藏版)》请在三一文库上搜索。

1、C#菜鸟做这个东东竟然花了快三天的时间了,真是菜,菜,菜?F面是我用C#写的一个简单的TCP通信,主要的功能有(1) 多个客户端与服务器间的数据交流(2) 可以实现群发的功能(3 )客户端与服务端可以进行文件的传输主要用到的知识:F面的是界面:口-孤天弱容户揣TCP 里的 socket、 多线程 Thread、与月 与冃 与冃与月 与月 与M与冃 与月遥中鼬功! : !瘙成妙! ! !瘙範功! ! !:宅朴逵电功! ! ! j ui jp 逵冠功! ! !Ir . 172.16.12. 1球质功! ! !:寒申PORT 6066昵称:雪连接服势端发送消息选择文件岌送文件J鞭天宣底服努蔬I昌I回

2、I 0 J盏而s雷 而 山山 -1而户尸S畫成成成成成成成IF 172.16 12.12FOK S068172.16.12.12:58063 172. 16.12.12:58064 172.IB.12.12:56065 1T2. 16.12.12:58066 1T2. IB. 12.12:58067 172. 15.12.12:56068 172.10.12.12:58069 1T2. 16.12.12 56OT0发送消息选择文件发送文件服务端代码:F面分别是服务端和客户端的代码,如若借用,请标明出处csharp view pla in copypri nt?using System;usin

3、g System.Collect ion s.Ge n eric;using System.Comp onen tModel;using System.Data;using System.Draw ing;using System丄inq;using System.Text;using System.Wi n dows.Forms;using System.Net.Sockets;usi ng System.Net; /IP , IPAddress, IPE ndPoi nt ,端口等;using System.Thread ing;using Syste m.IO;n amespace _1

4、1111public partial class frm_server : Form public frm server。In itializeComp onen t();TextBox.CheckForlllegalCrossThreadCalls = false;线程;Thread threadWatch = null; / 负责监听客户端连接请求的 Socket socketWatch = null;Dictionary<string, Socket> dict = new Dictionary<string, Socket>();Dictionary<st

5、ring, Thread> dictThread = new Dictionary<string, Thread>();private void btnBeginListen_Click(object sender, EventArgs e)/ 创建负责监听的套接字,注意其中的参数;socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); / 得文本框中的 IP 对象;IPAddress address = IPAddress.Parse(txtIp.T

6、ext.Trim();/ 创建包含 ip 和端口号的网络节点对象;IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim();try/ 将负责监听的套接字绑定到唯一的 ip 和端口上; socketWatch.Bind(endPoint);catch (SocketException se)MessageBox.Show(" 异常: "+se.Message);return;/ 设置监听队列的长度; socketWatch.Listen(10);/ 创建负责监听的线程;threadW

7、atch = new Thread(WatchConnecting); threadWatch.IsBackground = true;threadWatch.Start();ShowMsg(" 服务器启动监听成功! ");/ <summary>/ 监听客户端请求的方法;/ </summary>void WatchConnecting()while (true) / 持续不断的监听客户端的连接请求;/ 开始监听客户端连接请求, Accept 方法会阻断当前的线程;与该客Socket sokConnection = socketWatch.Accept

8、(); / 一旦监听到一个客户端的请求,就返回一个 户端通信的 套接字;/ 想列表控件中添加客户端的 IP 信息; lbOnline.Items.Add(sokConnection.RemoteEndPoint.ToString();/ 将与客户端连接的 套接字 对象添加到集合中; dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);ShowMsg(" 客户端连接成功! ");Thread thr = new Thread(RecMsg); thr.IsBackground = true; thr

9、.Start(sokConnection);将新建的线程 添加 到线 程的集合dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); / 中去。 void RecMsg(object sokConnectionparn)Socket sokClient = sokConnectionparn as Socket;while (true)/ 定义一个 2M 的缓存区;byte arrMsgRec = new byte1024 * 1024 * 2;/ 将接受到的数据存入到输入 arrMsgRec 中;int length = -

10、1;trylength = sokClient.Receive(arrMsgRec); /接收数据,并返回数据的长度;catch (SocketException se)ShowMsg(" 异常: " + se.Message);/ 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(sokClient.RemoteEndPoint.ToString();/ 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(sokClient.RemoteEndPoint.ToString();/ 从列表中移除被中断的连接 IP l

11、bOnline.Items.Remove(sokClient.RemoteEndPoint.ToString(); break;catch (Exception e)ShowMsg(" 异常: " + e.Message);/ 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(sokClient.RemoteEndPoint.ToString();/ 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(sokClient.RemoteEndPoint.ToString();/ 从列表中移除被中断的连接 IP lbOn

12、line.Items.Remove(sokClient.RemoteEndPoint.ToString(); break;if (arrMsgRec0 = 0) / 表示接收到的是数据;string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec,1, length-1);/将接受到的字节数据转化成字符串;ShowMsg(strMsg);if (arrMsgRec0 = 1) / 表示接收到的是文件;SaveFileDialog sfd = new SaveFileDialog();if (sfd.ShowDialog(this)

13、= System.Windows.Forms.DialogResult.OK)/ 在上边的 sfd.ShowDialog () 的括号里边一定要加上 this 否则就不会弹出 另存为 的 对话框,而弹 出的是本类的其他窗口, ,这个一定要注意! !【解释:加了 this 的 sfd.ShowDialog(this) , “另存为 ”窗口的指针才能被 SaveFileDialog 的对象调用,若不加 thisSaveFileDialog 的对象调用的 是本类的其他窗口了,当然不弹出 “另存为 ”窗口。】string fileSavePath = sfd.FileName;/ 获得文件保存的路径;

14、/ 创建文件流,然后根据路径创建文件;using (FileStream fs = new FileStream(fileSavePath, FileMode.Create)fs.Write(arrMsgRec, 1, length - 1);ShowMsg(" 文件保存成功: " + fileSavePath);void ShowMsg(string str)txtMsg.AppendText(str + "rn");/ 发送消息private void btnSend_Click(object sender, EventArgs e)string s

15、trMsg = " 服务器 " + "rn" + " ->" + txtMsgSend.Text.Trim() + "rn"byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); /将要发送的字符串转换成 Utf-8 字节数组;byte arrSendMsg=new bytearrMsg.Length+1; arrSendMsg0 = 0; /表示发送的是消息数据Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, a

16、rrMsg.Length);string strKey = ""strKey = lbOnline.Text.Trim();if (string.IsNullOrEmpty(strKey) / 判断是不是选择了发送的对象;MessageBox.Show(" 请选择你要发送的好友! ! ");elsedictstrKey.Send(arrSendMsg);/ 解决了 sokConnection 是局部变量, 不能再本函数中引用的 问题; ShowMsg(strMsg); txtMsgSend.Clear();/ <summary>/ 群发消息/

17、 </summary>/ <param name="sender"></param>/ <param name="e"> 消息 </param>private void btnSendToAll_Click(object sender, EventArgs e)string strMsg = " 服务器 " + "rn" + " ->" + txtMsgSend.Text.Trim() + "rn"byte a

18、rrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); /将要发送的字符串转换成 Utf-8 字节数组;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; / IP

19、, IPAddress, IPEndPoint ,端口等;using System.Threading;using System.IO;namespace _11111public partial class frm_server : Formpublic frm_server()InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false;Thread threadWatch = null; / 负责监听客户端连接请求的 线程;Socket socketWatch = null;Dictionary<str

20、ing, Socket> dict = new Dictionary<string, Socket>();Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();private void btnBeginListen_Click(object sender, EventArgs e) / 创建负责监听的套接字,注意其中的参数;socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream

21、, ProtocolType.Tcp);/ 获得文本框中的 IP 对象;IPAddress address = IPAddress.Parse(txtIp.Text.Trim();/ 创建包含 ip 和端口号的网络节点对象;IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim(); try/ 将负责监听的套接字绑定到唯一的 ip 和端口上; socketWatch.Bind(endPoint);catch (SocketException se)MessageBox.Show(" 异常: &

22、quot;+se.Message);return;/ 设置监听队列的长度; socketWatch.Listen(10);/ 创建负责监听的线程; threadWatch = new Thread(WatchConnecting);threadWatch.IsBackground = true; threadWatch.Start();ShowMsg(" 服务器启动监听成功! ");/ <summary>/ 监听客户端请求的方法;/ </summary>void WatchConnecting()while (true) / 持续不断的监听客户端的连

23、接请求;/ 开始监听客户端连接请求, Accept 方法会阻断当前的线程;Socket sokConnection = socketWatch.Accept(); / 一旦监听到一个客户端的 请 求,就返回一个与该客户端通信的 套接字;/ 想列表控件中添加客户端的 IP 信息; lbOnline.Items.Add(sokConnection.RemoteEndPoint.ToString();/ 将与客户端连接的 套接字 对象添加到集合中; dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection); ShowMsg(&q

24、uot; 客户端连接成功! ");Thread thr = new Thread(RecMsg); thr.IsBackground = true; thr.Start(sokConnection); dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); / 将新 建的线程 添加 到线程的集合中去。 void RecMsg(object sokConnectionparn) Socket sokClient = sokConnectionparn as Socket;while (true)/ 定义一个 2M 的缓

25、存区; byte arrMsgRec = new byte1024 * 1024 * 2;/ 将接受到的数据存入到输入 arrMsgRec 中; int length = -1; trylength = sokClient.Receive(arrMsgRec); / 接收数据,并返回数据 的长ShowMsg(" 文件保存成功:" + fileSavePath);度;catch (SocketException se)ShowMsg(" 异常: " + se.Message);/ 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(

26、sokClient.RemoteEndPoint.ToString();/ 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(sokClient.RemoteEndPoint.ToString();/ 从列表中移除被中断的连接 IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString(); break;catch (Exception e)ShowMsg(" 异常: " + e.Message);/ 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(sok

27、Client.RemoteEndPoint.ToString();/ 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(sokClient.RemoteEndPoint.ToString();/ 从列表中移除被中断的连接 IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString(); break;if (arrMsgRec0 = 0) / 表示接收到的是数据; string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec,1, length

28、-1);/ 将接受到的字节数据转化成 字符串;ShowMsg(strMsg);if (arrMsgRec0 = 1) / 表示接收到的是文件;SaveFileDialog sfd = new SaveFileDialog();if (sfd.ShowDialog(this) = System.Windows.Forms.DialogResult.OK)/ 在上边的 sfd.ShowDialog () 的括号里边一定要加上this 否则就不会弹出 另存为 的对话框, 而弹出的是本类的其他窗口, ,这个一定要注意! ! 【解释:加了 this 的 sfd.ShowDialog(this) , “另

29、存为 ”窗口的指针才能被 SaveFileDialog 的对 象 调用,若不加 thisSaveFileDialog 的对象调用的是本类的其他窗口了, 当然不弹出 “另存为 ” 窗 口。】string fileSavePath = sfd.FileName;/ 获得文件保存的路 径; / 创建文件流,然后根据路径创建文件;using (FileStream fs= new FileStream(fileSavePath,FileMode.Create)fs.Write(arrMsgRec, 1, length - 1);void ShowMsg(string str) txtMsg.Appen

30、dText(str + "rn");/ 发送消息private void btnSend_Click(object sender, EventArgs e)string strMsg = " 服务器 " + "rn" + "->" + txtMsgSend.Text.Trim() + "rn"byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); /将要发送的字 符串转换成 Utf-8 字节数组;byte arrSendMsg=n

31、ew bytearrMsg.Length+1; arrSendMsg0 = 0; / 表示发送的是消 息数据 Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length); string strKey = "" strKey = lbOnline.Text.Trim();if (string.IsNullOrEmpty(strKey)/ 判断是不是选择了发送的对象; MessageBox.Show(" 请选择你要发送的好友! ! "); else dictstrKey.Send(arrSendMsg)

32、;/ 解决了 sokConnection 是局部变量, 不能 再 本函数中引用的问题;ShowMsg(strMsg); txtMsgSend.Clear();/ <summary>/ 群发消息/ </summary>/ <param name="sender"></param>/ <param name="e"> 消息 </param>private void btnSendToAll_Click(object sender, EventArgs e)string strMsg =

33、" 服务器 " + "rn" + "->" + txtMsgSend.Text.Trim() + "rn"byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); /将要发送的字 符串转换成 Utf-8 字节数组;csharp view plaincopyprint?csharp view plaincopyprint?<span style="font-size: 14px;"> byte arrSendMsg = n

34、ew bytearrMsg.Length + 1; /上次写的 时候把这一段给弄掉了, 实在是抱歉哈 用来标识发送是数据而不是文件, 如果没有这一段 的客户端就接 收不到消息了 arrSendMsg0 = 0; / 表示发送的是消息数据Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);</span>byte arrSendMsg = new bytearrMsg.Length + 1; /上次写的时候把这一段给 弄掉了,实在是抱歉哈 用来标识发送是数据而不是文件, 如果没有这一段的客户端就接收 不到消息了 arrSe

35、ndMsg0 = 0; / 表示发送的是消息数据Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);csharp view plaincopyprint?foreach (Socket s in dict.Values) s.Send(arrMsg);ShowMsg(strMsg); txtMsgSend.Clear();ShowMsg ( ”群发完毕 ”;) / 选择要发送的文件private void btnSelectFile_Click_1(object sender, EventArgs e)OpenFileDialog

36、 ofd = new OpenFileDialog();ofd.InitialDirectory = "D:" ;if (ofd.ShowDialog() = System.Windows.Forms.DialogResult.OK) txtSelectFile.Text = ofd.FileName ; / 文件的发送private void btnSendFile_Click_1(object sender, EventArgs e)if (string.IsNullOrEmpty(txtSelectFile.Text)MessageBox.Show(" 请选

37、择你要发送的文件! ! ");else/ 用文件流打开用户要发送的文件;using (FileStream fs = new FileStream(txtSelectFile.Text, FileMode.Open)string fileName=System.IO.Path.GetFileName(txtSelectFile.Text);string fileExtension=System.IO.Path.GetExtension(txtSelectFile.Text);string strMsg = " 我给你发送的文件为: "+fileName+fileE

38、xtension+"rn"byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); /将要发送的字符串转换成 Utf-8 字节数组;byte arrSendMsg = new bytearrMsg.Length + 1; arrSendMsg0 = 0; /表示发送的是消息数据Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);bool fff = true;string strKey = ""strKey = lbOnline.Te

39、xt.Trim();if (string.IsNullOrEmpty(strKey) / 判断是不是选择了发送的对象;MessageBox.Show(" 请选择你要发送的好友! ! ");else问题;问题;dictstrKey.Send(arrSendMsg);/ 解决了 sokConnection 是局部变量, 不能再本函数中引用的 byte arrFile = new byte1024 * 1024 * 2;int length = fs.Read(arrFile, 0, arrFile.Length); / 将文件中的数据读到 arrFile 数组中; byte a

40、rrFileSend = new bytelength + 1;arrFileSend0 = 1; / 用来表示发送的是文件数据; Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);/ 还有一个 CopyTo 的方法,但是在这里不适合; 当然还可以用 for 循环自己转化;/ sockClient.Send(arrFileSend);/ 发送数据到服务端;dictstrKey.Send(arrFileSend);/ 解决了 sokConnection 是局部变量,不能再本函数中引用的 txtSelectFile.Clear(); txtS

41、electFile.Clear();foreach (Socket s in dict.Values)s.Send(arrMsg);ShowMsg(strMsg);txtMsgSend.Clear();ShowMsg ( ”群发完毕 ”;)/ 选择要发送的文件private void btnSelectFile_Click_1(object sender, EventArgs e)OpenFileDialog ofd = new OpenFileDialog() ; ofd.InitialDirectory = "D:" ;if (ofd.ShowDialog() = Sy

42、stem.Windows.Forms.DialogResult.OK)txtSelectFile.Text = ofd.FileName ; / 文件的发送private void btnSendFile_Click_1(object sender, EventArgs e) if (string.IsNullOrEmpty(txtSelectFile.Text)!");MessageBox.Show ( ”请选择你要发送的文件!else/ 用文件流打开用户要发送的文件;using (FileStream fs = new FileStream(txtSelectFile.Text,

43、 FileMode.Open) string fileName=System.IO.Path.GetFileName(txtSelectFile.Text) ; stringfileExtension=System.IO.Path.GetExtension(txtSelectFile.Text) ; stringstrMsg =" 我 给 你 发 送 的 文 件 为 :"+fileName+fileExtension+"rn"byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg) ; / 将要 发

44、 送的字符串转换成 Utf-8 字节数组;byte arrSendMsg = new bytearrMsg.Length + 1; arrSendMsg0 = 0 ; /表示发送的是消息数据 Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length) ; bool fff = true ; string strKey = "" ; strKey = lbOnline.Text.Trim() ; 象;MessageBox.Show(" 请选择你要发送的好友! ! ");elsedictstrKey.S

45、end(arrSendMsg);/ 解决了 sokConnection 是局部变量, 不能 再本函数中引用的问题;byte arrFile = new byte1024 * 1024 * 2;int length = fs.Read(arrFile, 0, arrFile.Length); /将文件中的数据读 到arrFile 数组中;byte arrFileSend = new bytelength + 1;arrFileSend0 = 1; / 用来表示发送的是文件数据; Buffer.BlockCopy(arrFile,0, arrFileSend, 1, length);/ 还有一个

46、CopyTo 的方法, 但是在这里不适合; 当然还可以用 for 循环自 己转化;/ sockClient.Send(arrFileSend);/ 发送数据到服务端; dictstrKey.Send(arrFileSend);/ 解决了 sokConnection 是局部变量, 不能再本函数中引用的问题; txtSelectFile.Clear(); txtSelectFile.Clear();客户端代码:csharp view plaincopyprint?using System;using System.Collections.Generic;using System.Component

47、Model;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.Threading;using System.IO;namespace _2222222 public partial class frmClient : Form public frmClient()InitializeComponent();TextBox.CheckForIllegalCros

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1