
自己定制一个协议
Server:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace _123_服务器与客户端交互_聊天_Server{public partial class FormServer : Form{public FormServer(){InitializeComponent();}/// <summary>/// 点击按钮开始监听/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnStart_Click(object sender, EventArgs e){try{//创建一个负责监听(服务器IP地址和端口号)的Socket // 网络协议IP V4版本 流式使用TCP协议Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建IP地址和端口号对象IPAddress ip = IPAddress.Any; //客户端的活动地址,可变 //IPAddress.Parse(txtServer.Text);这样子只会把txtServer.Text作为IP地址不可变。IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));//让负责监听的Socket绑定IP地址和端口号socketWatch.Bind(point);ShowMsg("监听成功");//设置监听队列socketWatch.Listen(10);//在某一时间点内最大容量Thread th = new Thread(Listen);th.IsBackground = true;th.Start(socketWatch);}catch{MessageBox.Show("Server项目的(btnStart_Click())可能出问题了,请找大师。");}}/// <summary>/// 将字符串显示在Log文本框中/// </summary>/// <param name="str">即将要显示的字符串</param>public void ShowMsg(string str){txtLog.AppendText(str + "\r\n");}//将远程连接的客户端IP地址和Socket存入集合中Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();//创建跟客户端通信的Socket类的变量Socket socketSend;/// <summary>/// 等待客户端的连接,并且创建与之通信的Socket/// </summary>public void Listen(object o){Socket socketWatch = o as Socket;while (true){try{//负责监听的Socket 来接受客户端的连接(等待客户端连接) 并且创建跟客户端通信的Socket//负责和客户端通信的SocketsocketSend = socketWatch.Accept();//将此时客户端ip和SocketSend存入dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);//将此时客户端的ip地址和端口号存入下拉框中cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());//将谁(远程终结点)连接显示在文本框内ShowMsg(socketSend.RemoteEndPoint.ToString() + ":连接成功");//获取远程终结点//开启一个新线程,不停地接受客户端发来的消息Thread th = new Thread(Receive);th.IsBackground = true;th.Start(socketSend);}catch{MessageBox.Show("Server项目的(Listen())可能出问题了,请找大师。");}}}/// <summary>/// 服务器端不停地接受客户端发来的消息/// </summary>/// <param name="o"></param>public void Receive(object o){Socket socketSend = o as Socket;while (true){try{//客户端连接成功后,服务器应该接受客户端发来的消息byte[] buffer = new byte[1024 * 1024 * 2];//实际接收到的有限字节数int r = socketSend.Receive(buffer);if (r == 0){break;}string input = Encoding.UTF8.GetString(buffer, 0, r);//显示客户端发送的数据ShowMsg(DateTime.Now + "\r\n" + socketSend.RemoteEndPoint + ":" + input);}catch{//MessageBox.Show("Server项目的(Receive())可能出问题了,请找大师。");}}}/// <summary>/// 取消不可跨线程访问/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void FormServer_Load(object sender, EventArgs e){//取消不可跨线程访问Control.CheckForIllegalCrossThreadCalls = false;}private void FormServer_DoubleClick(object sender, EventArgs e){////当你点击关闭窗口的时候,判断线程是否为null//if (th != null)//{// //th.Abort();//线程被Abort后就不能被Start了// th = null;//}}/// <summary>/// 服务器给客户端发送消息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSend_Click(object sender, EventArgs e){string input = txtMsg.Text.Trim();byte[] buffer = Encoding.UTF8.GetBytes(input);//制定协议 字节数组第一位为0:文本消息 1:文件 2:震动List<byte> list = new List<byte>();list.Add(0);//给第一位赋值为0list.AddRange(buffer);//将泛型集合穿换成数组byte[] newBuffer = list.ToArray(); //buffer = list.ToArray();不可以 数组长度不一样了//获得用户在下拉框中选中的IP地址string ip = cboUsers.SelectedItem.ToString();dicSocket[ip].Send(newBuffer);//socketSend.Send(buffer);//发送成功后清除当前文本txtMsg.Clear();txtMsg.Focus();}private void btnSelect_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Title = "客官,请选择你要发送的文件";ofd.InitialDirectory = @"C:\Users\46124\Desktop";ofd.Filter = "文本文件|*.txt|媒体文件|*.wav|媒体文件|*.mp4|所有文件|*.*";ofd.ShowDialog();//将对话框选择的文件的全路径放入文本框中txtPath.Text = ofd.FileName;}/// <summary>/// 点击发送文件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSendFile_Click(object sender, EventArgs e){//获得要发送文件的路径string path = txtPath.Text;using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read)){byte[] buffer = new byte[1024 * 1024 * 5];int r = fsRead.Read(buffer, 0, buffer.Length);//制定协议 字节数组第一位为0:文本消息 1:文件 2:震动List<byte> list = new List<byte>();list.Add(1);list.AddRange(buffer);byte[] newBuffer = list.ToArray();//通过下拉框获取需要发送客户端的IP然后发送字节数组dicSocket[cboUsers.SelectedItem.ToString()].Send(newBuffer);MessageBox.Show("发送成功");}}/// <summary>/// 发送振动/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnVibrate_Click(object sender, EventArgs e){byte[] buffer = new byte[1];buffer[0] = 2;//通过下拉框获取需要发送客户端的IP然后发送字节数组dicSocket[cboUsers.SelectedItem.ToString()].Send(buffer);}private void btnClose_Click(object sender, EventArgs e){this.Close();}}}
Client:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace _124_服务器与客户端交互_聊天_Client{public partial class FormClient : Form{public FormClient(){InitializeComponent();}Socket socketSend;private void button1_Click(object sender, EventArgs e){try{//创建负责通信的SocketsocketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建IP和端口号连接服务器IPAddress ip = IPAddress.Parse(txtServer.Text);IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));//获得要连接的远程服务器应用程序的IP地址和端口号socketSend.Connect(point);ShowMsg("连接成功");//开启一个新的线程不停地接受服务器发送来的消息Thread th = new Thread(Receive);th.IsBackground = true;th.Start();}catch{MessageBox.Show("连接服务器时出错,请找大师");}}/// <summary>/// 将字符串显示在Log文本框中/// </summary>/// <param name="str">即将要显示的字符串</param>public void ShowMsg(string str){txtLog.AppendText(str + "\r\n");}/// <summary>/// 客户端给服务器发送消息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSend_Click(object sender, EventArgs e){//将客户端发送的数据string转化成byte发送string input = txtMsg.Text.Trim();byte[] buffer = Encoding.UTF8.GetBytes(input);socketSend.Send(buffer);//发送成功后清除当前文本txtMsg.Clear();txtMsg.Focus();}/// <summary>/// 不停的接受服务器发来的消息/// </summary>public void Receive(){try{while (true){byte[] buffer = new byte[1024 * 1024 * 2];int r = socketSend.Receive(buffer);if (r == 0){break;}//使用协议判断字节数组第一位 0:文本消息 1:文件 2:震动if (buffer[0] == 0){string input = Encoding.UTF8.GetString(buffer, 1, r - 1); //r-1是因为数组加了一位 数量多了一个ShowMsg(DateTime.Now + "\r\n" + socketSend.RemoteEndPoint + ":" + input);}else if (buffer[0] == 1){SaveFileDialog sfd = new SaveFileDialog();sfd.InitialDirectory = @"C:\Users\46124\Desktop";sfd.Title = "客官,请选择保存文件的地址";sfd.Filter = "文本文件|*.txt|媒体文件|*.wav|媒体文件|*.mp4|所有文件|*.*";sfd.ShowDialog(this);string path = sfd.FileName;using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)){fsWrite.Write(buffer, 1, r - 1);MessageBox.Show("接受成功");}}else if (buffer[0] == 2){Vibrate();}}}catch{MessageBox.Show("(Client项目的Receive())可能出问题了,请找大师。");}}private void FormClient_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;}/// <summary>/// 振动/// </summary>public void Vibrate(){for (int i = 0; i < 2000; i++){//Random r = new Random();//int rNumber = r.Next(100, 250);//this.Location = new Point(this.Location.X + rNumber, this.Location.Y + rNumber);this.Location = new Point(200, 200);this.Location = new Point(300, 300);}}}}
