关于一个 Scoket 通信的基本代码和一个基本的通信.doc_第1页
关于一个 Scoket 通信的基本代码和一个基本的通信.doc_第2页
关于一个 Scoket 通信的基本代码和一个基本的通信.doc_第3页
关于一个 Scoket 通信的基本代码和一个基本的通信.doc_第4页
关于一个 Scoket 通信的基本代码和一个基本的通信.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

关于一个 Scoket 通信的基本代码和一个基本的通信实现一个服务器和N个客户端的互相聊天Server:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Net;/Endpointusing System.Net.Sockets;/包含套接字using System.Text;using System.Windows.Forms;using System.Threading;using System.IO;namespace Server public partial class Form1 : Form public Form1() InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false;/关闭跨线程修改控件检查 Socket sokWatch = null;/负责监听 客户端段 连接请求的 套接字 Thread threadWatch = null;/负责 调用套接字, 执行 监听请求的线程 /开启监听 按钮 private void btnStartListen_Click(object sender, EventArgs e) /实例化 套接字 (ip4寻址协议,流式传输,TCP协议) sokWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); /创建 ip对象 IPAddress address = IPAddress.Parse(txtIP.Text.Trim(); /创建网络节点对象 包含 ip和port IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim(); /将 监听套接字 绑定到 对应的IP和端口 sokWatch.Bind(endpoint); /设置 监听队列 长度为10(同时能够处理 10个连接请求) sokWatch.Listen(10); threadWatch = new Thread(StartWatch); threadWatch.IsBackground = true; threadWatch.Start(); txtShow.AppendText(启动服务器成功.rn); /Dictionary dictSocket = new Dictionary(); Dictionary dictConn = new Dictionary(); bool isWatch = true; #region 1.被线程调用 监听连接端口 / / 被线程调用 监听连接端口 / void StartWatch() while (isWatch) /threadWatch.SetApartmentState(ApartmentState.STA); /监听 客户端 连接请求,但是,Accept会阻断当前线程 Socket sokMsg = sokWatch.Accept();/监听到请求,立即创建负责与该客户端套接字通信的套接字 ConnectionClient connection = new ConnectionClient(sokMsg, ShowMsg, RemoveClientConnection); /将负责与当前连接请求客户端 通信的套接字所在的连接通信类 对象 装入集合 dictConn.Add(sokMsg.RemoteEndPoint.ToString(), connection); /将 通信套接字 加入 集合,并以通信套接字的远程IpPort作为键 /dictSocket.Add(sokMsg.RemoteEndPoint.ToString(), sokMsg); /将 通信套接字的 客户端IP端口保存在下拉框里 cboClient.Items.Add(sokMsg.RemoteEndPoint.ToString(); ShowMsg(接收连接成功.); /启动一个新线程,负责监听该客户端发来的数据 /Thread threadConnection = new Thread(ReciveMsg); /threadConnection.IsBackground = true; /threadConnection.Start(sokMsg); #endregion bool isRec = true;/与客户端通信的套接字 是否 监听消息 #region 发送消息 到指定的客户端 -btnSend_Click /发送消息 到指定的客户端 private void btnSend_Click(object sender, EventArgs e) /byte arrMsg = System.Text.Encoding.UTF8.GetBytes(txtInput.Text.Trim(); /从下拉框中 获得 要哪个客户端发送数据 string connectionSokKey = cboClient.Text; if (!string.IsNullOrEmpty(connectionSokKey) /从字典集合中根据键获得 负责与该客户端通信的套接字,并调用send方法发送数据过去 dictConnconnectionSokKey.Send(txtInput.Text.Trim(); /sokMsg.Send(arrMsg); else MessageBox.Show(请选择要发送的客户端); #endregion /发送闪屏! private void btnShack_Click(object sender, EventArgs e) string connectionSokKey = cboClient.Text; if (!string.IsNullOrEmpty(connectionSokKey) dictConnconnectionSokKey.SendShake(); else MessageBox.Show(请选择要发送的客户端); /群闪 private void btnShackAll_Click(object sender, EventArgs e) foreach (ConnectionClient conn in dictConn.Values) conn.SendShake(); #region 2 移除与指定客户端的连接 +void RemoveClientConnection(string key) / / 移除与指定客户端的连接 / / 指定客户端的IP和端口 public void RemoveClientConnection(string key) if (dictConn.ContainsKey(key) dictConn.Remove(key); cboClient.Items.Remove(key); #endregion /选择要发送的文件 private void btnChooseFile_Click(object sender, EventArgs e) OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() = System.Windows.Forms.DialogResult.OK) txtFilePath.Text = ofd.FileName; /发送文件 private void btnSendFile_Click(object sender, EventArgs e) /拿到下拉框中选中的客户端IPPORT string key = cboClient.Text; if (!string.IsNullOrEmpty(key) dictConnkey.SendFile(txtFilePath.Text.Trim(); #region 向文本框显示消息 -void ShowMsg(string msgStr) / / 向文本框显示消息 / / 消息 public void ShowMsg(string msgStr) txtShow.AppendText(msgStr + rn); #endregion private void btnSendMsgAll_Click(object sender, EventArgs e) foreach (ConnectionClient conn in dictConn.Values) conn.Send(txtInput.Text.Trim(); 新建一个中间类, ConnectionClientusing System;using System.Collections.Generic;using System.Threading;using System.Net;using System.Net.Sockets;using System.Text;using System.IO;namespace Server / / 与客户端的 连接通信类(包含了一个 与客户端 通信的 套接字,和线程) / public class ConnectionClient Socket sokMsg; DGShowMsg dgShowMsg;/负责 向主窗体文本框显示消息的方法委托 DGShowMsg dgRemoveConnection;/ 负责 从主窗体 中移除 当前连接 Thread threadMsg; #region 构造函数 / / / / 通信套接字 / 向主窗体文本框显示消息的方法委托 public ConnectionClient(Socket sokMsg, DGShowMsg dgShowMsg, DGShowMsg dgRemoveConnection) this.sokMsg = sokMsg; this.dgShowMsg = dgShowMsg; this.dgRemoveConnection = dgRemoveConnection; this.threadMsg = new Thread(RecMsg); this.threadMsg.IsBackground = true; this.threadMsg.Start(); #endregion bool isRec = true; #region 02负责监听客户端发送来的消息 void RecMsg() while (isRec) try byte arrMsg = new byte1024 * 1024 * 2; /接收 对应 客户端发来的消息 int length = sokMsg.Receive(arrMsg); /将接收到的消息数组里真实消息转成字符串 string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg, 0, length); /通过委托 显示消息到 窗体的文本框 dgShowMsg(strMsg); catch (Exception ex) isRec = false; /从主窗体中 移除 下拉框中对应的客户端选择项,同时 移除 集合中对应的 ConnectionClient对象 dgRemoveConnection(sokMsg.RemoteEndPoint.ToString(); #endregion #region 03向客户端发送消息 / / 向客户端发送消息 / / public void Send(string strMsg) byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); byte arrMsgFinal = new bytearrMsg.Length+1; arrMsgFinal0 = 0;/设置 数据标识位等于0,代表 发送的是 文字 arrMsg.CopyTo(arrMsgFinal, 1); sokMsg.Send(arrMsgFinal); #endregion #region 04向客户端发送文件数据 +void SendFile(string strPath) / / 04向客户端发送文件数据 / / 文件路径 public void SendFile(string strPath) /通过文件流 读取文件内容 using (FileStream fs = new FileStream(strPath, FileMode.OpenOrCreate) byte arrFile = new byte1024 * 1024 * 2; /读取文件内容到字节数组,并 获得 实际文件大小 int length = fs.Read(arrFile, 0, arrFile.Length); /定义一个 新数组,长度为文件实际长度 +1 byte arrFileFina = new bytelength + 1; arrFileFina0 = 1;/设置 数据标识位等于1,代表 发送的是文件 /将 文件数据数组 复制到 新数组中,下标从1开始 /arrFile.CopyTo(arrFileFina, 1); Buffer.BlockCopy(arrFile, 0, arrFileFina, 1, length); /发送文件数据 sokMsg.Send(arrFileFina);/, 0, length + 1, SocketFlags.None); #endregion #region 05向客户端发送闪屏 / / 向客户端发送闪屏 / / public void SendShake() byte arrMsgFinal = new byte1; arrMsgFinal0 = 2; sokMsg.Send(arrMsgFinal); #endregion #region 06关闭与客户端连接 / / 关闭与客户端连接 / public void CloseConnection() isRec = false; #endregion 最后就是我们的客户端了噢.Client:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Net.Sockets;using System.Net;using System.Threading;using System.Windows.Forms;using System.IO;namespace Client public partial class Form1 : Form public Form1() InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false; Socket sokClient = null;/负责与服务端通信的套接字 Thread threadClient = null;/负责 监听 服务端发送来的消息的线程 bool isRec = true;/是否循环接收服务端数据 private void btnConnect_Click(object sender, EventArgs e) /实例化 套接字 sokClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); /创建 ip对象 IPAddress address = IPAddress.Parse(txtIP.Text.Trim(); /创建网络节点对象 包含 ip和port IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim(); /连接 服务端监听套接字 sokClient.Connect(endpoint); /创建负责接收 服务端发送来数据的 线程 threadClient = new Thread(ReceiveMsg); threadClient.IsBackground = true; /如果在win7下要通过 某个线程 来调用 文件选择框的代码,就需要设置如下 threadClient.SetApartmentState(ApartmentState.STA); threadClient.Start(); / / 接收服务端发送来的消息数据 / void ReceiveMsg() while (isRec) byte msgArr = new byte1024 * 1024 * 1;/接收到的消息的缓冲区 int length=0; /接收服务端发送来的消息数据 length =sokClient.Receive(msgArr);/Receive会阻断线程 if (msgArr0 = 0)/发送来的是文字 string strMsg = System.Text.Encoding.UTF8.GetString(msgArr, 1, length - 1); txtShow.AppendText(strMsg + rn); else if (msgArr0 = 1) /发送来的是文件 SaveFileDialog sfd = new SaveFi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论