//客户端
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; namespace ConsoleClient { class Program { static void Main(string[] args) { ScoketClient client = new ScoketClient(); //测试不停发送消息 for (int i = 0; i < 10; i++) { client.SendMessage("Welcom To QiKu Edu,Welcom To QiKu Edu,Welcom To QiKu Edu,Welcom To QiKu Edu,Welcom To QiKu Edu"); } while (true) { string msg = Console.ReadLine(); client.SendMessage(msg); } } } } public class ScoketClient { /// <summary> /// 客户端 /// </summary> /// <param name="args"></param> string ip = "192.168.11.36"; int port = 8500; NetworkStream stream; byte[] buffer; int BuffseSize = 8192; public ScoketClient() { TcpClient clien = new TcpClient(); clien.Connect(ip, port); Console.WriteLine("客户端链接服务器" + clien.Client.RemoteEndPoint); stream = clien.GetStream(); Console.WriteLine("输入需要发送的消息:"); buffer = new byte[8192]; stream.BeginRead(buffer, 0, buffer.Length, ReadAsync, null); } void ReadAsync(IAsyncResult result) { try { int readCount = stream.EndRead(result); if (readCount == 0) throw new Exception("读取到0字节"); string msg = Encoding.UTF8.GetString(buffer, 0, readCount); Console.WriteLine("接收到消息 ->" + msg); //加个锁 lock (stream)//再次开启读取 { Array.Clear(buffer, 0, buffer.Length); stream.BeginRead(buffer, 0, BuffseSize, ReadAsync, null); } } catch (Exception e) { Console.WriteLine(e.Message); } } //发送字符信息到服务端的方法 public void SendMessage(string msg) { //把内容转为byte[] byte[] temp = Encoding.UTF8.GetBytes(msg);//收到消息后转为byte数组 //把长度转为byte[] int lenth = temp.Length;//获取收到的消息的长度 byte[] head = BitConverter.GetBytes(lenth);//将int长度转换为4个byte //拼接最后的byte数组 MemoryStream mem = new MemoryStream(); //MemoryStream创建其支持存储区为内存的流。 mem.Write(head, 0, head.Length); mem.Write(temp, 0, temp.Length); //发送最终内容 byte[] result = mem.ToArray();//转为字节流 stream.Write(result, 0, result.Length); Console.WriteLine("发送消息 ->" + msg); } }
//服务器
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; class Program { static Dictionary<string, RemoteClient> dic = new Dictionary<string, RemoteClient>(); static void Main(string[] args) { IPAddress adress = IPAddress.Parse("192.168.11.36"); int port = 8500; TcpListener linstener = new TcpListener(adress, port); linstener.Start(); Console.WriteLine("开始侦听客户端"); while (true) { TcpClient client = linstener.AcceptTcpClient(); //接收到客户端后,交给RemoteClient去处理 RemoteClient remote = new RemoteClient(client); //存储接收的客户端 dic.Add(client.Client.RemoteEndPoint.ToString(), remote); } } public static void Broad(TcpClient client, string msg) { foreach (KeyValuePair<string, RemoteClient> item in dic) { string message = client.Client.RemoteEndPoint.ToString() + ":发送了:" + msg; item.Value.SendMessage(message); } } }
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; class RemoteClient { 定义一个集合,存储客户端信息 //static Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, Socket>() { }; public const int BufferSize = 8192; TcpClient tcpClient; NetworkStream stream;//网络流 byte[] buffer; //static List<NetworkStream> streams = new List<NetworkStream>(); public RemoteClient(TcpClient client) { 创建一个监听线程 //Thread theadwatch = new Thread(WatchConnecting); 将窗体线程设置为与后台同步,随着主线程结束而结束 //theadwatch.IsBackground = true; 启动线程 //theadwatch.Start(); this.tcpClient = client; Console.WriteLine(client.Client.RemoteEndPoint + "-> 连接成功"); stream = client.GetStream(); //streams.Add(stream); buffer = new byte[BufferSize]; //开启异步读取信息 stream.BeginRead(buffer, 0, BufferSize, ReadAsync, null); } void ReadAsync(IAsyncResult result) { try { int readCount = stream.EndRead(result); if (readCount == 0) throw new Exception("读取到0字节"); //抛出到逻辑层 OnReceive(buffer, readCount); //加个锁 lock (stream)//再次开启读取 { Array.Clear(buffer, 0, buffer.Length); stream.BeginRead(buffer, 0, BufferSize, ReadAsync, null); } } catch (Exception e) { Console.WriteLine(e.Message); } } MemoryStream mem = new MemoryStream(); //解密消息体 void OnReceive(byte[] bytes, int count)//源源不断的接收 { mem.Seek(0, SeekOrigin.End);//指针指到结尾 mem.Write(bytes, 0, count);//读多少写多少 mem.Seek(0, SeekOrigin.Begin);//指针指向开头 int headCount = 4; while (RemainingBytes() > headCount)//接收多条消息 { byte[] head = new byte[headCount]; mem.Read(head, 0, headCount); int length = BitConverter.ToInt32(head, 0); if (RemainingBytes() >= length)//说明后面的内容足够可以截 { //总是没读过的信息 byte[] content = new byte[length];//字节数组 mem.Read(content, 0, length);//读他的零位到length位 string msg = Encoding.UTF8.GetString(content);//指定字节数组解码为字符串 Console.WriteLine(msg); } else//如果不够长度 { mem.Position = mem.Position - headCount; break; } } //把剩余的写到mem的开头 byte[] remain = new byte[mem.Length - mem.Position]; mem.Read(remain, 0, remain.Length); mem.SetLength(0); mem.Write(remain, 0, remain.Length); } long RemainingBytes() { return mem.Length - mem.Position; } //发送给客户端消息 public void SendMessage(string msg) { byte[] temp = Encoding.UTF8.GetBytes(msg); //foreach (NetworkStream item in streams) //{ stream.Write(temp, 0, temp.Length); //} Console.WriteLine("回复客户端 ->" + msg); } }