因为在传输的时候服务器与客户端只以字节流的方式来完成数据的传输,那么我们就可以在不同的数据数里加一个标志。
代码如下 | 复制代码 |
MyCommon类:
[Serializable]
public class MyCommon { //定义标志 private int flag; public int Flag { get { return flag; } set { flag = value; } } //传输的字节数组 private byte[] buffer; public byte[] Buffer { get { return buffer; } set { buffer = value; } } } |
代码如下 | 复制代码 |
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;
using System.Net.Sockets; using System.Threading; using System.IO; using System.Runtime.Serialization.Formatters.Binary;
namespace MyChatServer { public partial class Form1 : Form { public Form1() { InitializeComponent(); //不检测跨线程操作的合法性 Control.CheckForIllegalCrossThreadCalls = false; } //当多用户连接到同一个服务器的时候,记录通信点与对应通信的socket,以字典的键值对来保存,方便调用,这样服务器就可以选择的来给不同的用户发送消息了 Dictionary Dictionary private void btnStart_Click_1(object sender, EventArgs e)
{ //ip地址 IPAddress ip = IPAddress.Parse(txtServer.Text); //当前计算机上任何可用的ip地址 //IPAddress ip = IPAddress.Any; IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPort.Text)); //创建负责监听的socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { //绑定ip和端口号 socket.Bind(point); //监听 socket.Listen(10); ShowMsg("开始监听");
} catch (Exception ex) { ShowMsg(ex.Message); return; } Thread th = new Thread(Listen);
th.IsBackground = true; th.Start(socket); } int count = 0; void Listen(object o) { Socket socket = o as Socket; while (count<100) { try { count++; //创建一个负责通信用的socket 阻塞窗体的运行 Socket connSocket = socket.Accept(); string s = connSocket.RemoteEndPoint.ToString(); ShowMsg(s + ":连接成功"); //记录通信用的socket dicSocket.Add(s, connSocket); cboUsers.Items.Add(s); //接收消息
Thread th = new Thread(RecMsg); th.IsBackground = true; th.Start(connSocket); dicThread.Add(s, th);
} catch (Exception ex) { ShowMsg(ex.Message); break; } } } void RecMsg(object o)
{ Socket connSocket = o as Socket; while (true) { try { //接收客户端发送过来的消息 byte[] buffer = new byte[1024 * 1024]; //num 接收到的实际有效的字节个数 int num = connSocket.Receive(buffer); string s = Encoding.UTF8.GetString(buffer, 0, num); ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + s); } catch (Exception ex) { ShowMsg(ex.Message); break; } } } void ShowMsg(string msg) { txtLog.AppendText(msg + "rn"); } //服务器发送消息
private void btnSend_Click(object sender, EventArgs e) { //获取文本框内容 转化成字节数组 byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); try { //List ////标志 0 文字 //list.Add(0); //list.AddRange(buffer); Common.MyCommon my = new Common.MyCommon(); my.Flag = 0; my.Buffer = buffer; //客户端的通信用的socket
//获取当前选中的客户端的ip地址 string s = cboUsers.Text; dicSocket[s].Send(Serialize(my)); } catch (Exception ex) { ShowMsg(ex.Message); } } private void Form1_Load(object sender, EventArgs e) { } //选择文件 private void btnSelect_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { txtPath.Text = ofd.FileName; } } //发送文件
private void btnSendFile_Click(object sender, EventArgs e) { string key = cboUsers.Text; using (FileStream fs = new FileStream(txtPath.Text,FileMode.Open)) { byte[] buffer = new byte[fs.Length]; fs.Read(buffer,0,buffer.Length); //List
////标志 1 文件 //list.Add(1); //list.AddRange(buffer); Common.MyCommon my = new Common.MyCommon();
my.Flag = 1; my.Buffer = buffer; dicSocket[key].Send(Serialize(my));
} } //震动 private void btnZD_Click(object sender, EventArgs e) { string key = cboUsers.Text; //byte[] buffer = new byte[1];
////标志 震动 //buffer[0] = 2; Common.MyCommon my = new Common.MyCommon(); my.Flag = 2; dicSocket[key].Send(Serialize(my));
} //序列化,我想把这个对象转换成一个数组,那就传进去对象给我返回数组吧
byte[] Serialize(Common.MyCommon my) { //先把这个对象转换成一个流,再把这个流转换成一个字节数组,这个流只是一个中转流,用内存流就可以了 using (MemoryStream stream = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(stream,my); //把序列化好的流转换成数组 byte[] buffer = stream.ToArray(); //返回出字节数组 return buffer; } } } } |
代码如下 | 复制代码 |
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;
using System.Net.Sockets; using System.Threading;
using System.IO; using System.Runtime.Serialization.Formatters.Binary;
namespace MyChatClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } Socket socket; private void btnStart_Click(object sender, EventArgs e) { //服务器的ip地址与端口 IPAddress ip = IPAddress.Parse(txtServer.Text); IPEndPoint point = new IPEndPoint(ip,int.Parse(txtPort.Text)); socket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { //连接服务器 socket.Connect(point); ShowMsg("连接成功"); //接收服务器发送的消息
Thread th = new Thread(RecMsg); th.IsBackground = true; th.Start(); } catch (Exception ex) { ShowMsg(ex.Message); } } //接收服务器发送过来的消息 void RecMsg() { while (true) { try { byte[] buffer = new byte[1024 * 1024]; int num = socket.Receive(buffer); Common.MyCommon my = Deserialize(buffer, num);
//当是文字
if(my.Flag == 0) { string s = Encoding.UTF8.GetString(my.Buffer, 0,my.Buffer.Length); ShowMsg(s); } //接收文件 else if (my.Flag == 1) { //提示是否保存文件 DialogResult dr = MessageBox.Show("是否保存文件?","提示",MessageBoxButtons.YesNo); if (dr == System.Windows.Forms.DialogResult.Yes) { SaveFileDialog sfd = new SaveFileDialog(); //保存文件 win7下使用的时候注意,必须加this if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { using (FileStream fs = new FileStream(sfd.FileName,FileMode.Create)) { fs.Write(my.Buffer,0,my.Buffer.Length); } } } } else if (my.Flag == 2) { //窗口置于顶层 this.TopMost = true; //震动 ZD(); } } catch (Exception ex) { ShowMsg(ex.Message); break; } } } void ShowMsg(string msg)
{ txtLog.AppendText(msg + "rn"); } //发送消息
private void btnSend_Click(object sender, EventArgs e) { if (socket != null) { try { byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); socket.Send(buffer); } catch (Exception ex) { ShowMsg(ex.Message); } } } private void Form1_Load(object sender, EventArgs e)
{ } //震动 string dir = "top"; int count = 10; void ZD() { for (int i = 0; i < count; i++) { if (dir == "top") { dir = "bottom"; this.Location = new Point(this.Location.X - 5, this.Location.Y - 5); } else { dir = "top"; this.Location = new Point(this.Location.X + 5, this.Location.Y + 5); } System.Threading.Thread.Sleep(50); } }
//反序列化,把一个字节数组转换成一个对象,
Common.MyCommon Deserialize(byte[] buffer,int num) { using (MemoryStream ms = new MemoryStream(buffer, 0, num)) { BinaryFormatter bf = new BinaryFormatter(); Common.MyCommon my = bf.Deserialize(ms) as Common.MyCommon; return my;
} } } } |