ScoketService
public partial class Form1 : Form { public Form1() { InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false;//关闭跨线程修改控件检查 } Socket sokWatch = null;//负责监听 客户端段 连接请求的 套接字 Task task; CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); Thread threadWatch = null;//负责 调用套接字, 执行 监听请求的线程 List<ClientIp> list = new List<ClientIp>(); private Socket[] ClientSocket;//为客户端建立的SOCKET连接 private void Form1_Load(object sender, EventArgs e) { ClientSocket = new Socket[65535]; } private void btnstart_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(sokWatch)); //threadWatch.IsBackground = true; threadWatch.Start(); this.ClientList.Items.Add("服务于 " + DateTime.Now.ToString() + " 开始运行."); //txtShow.AppendText("启动服务器成功...... "); btnstart.Enabled = false; } bool isWatch = true; bool isRec = true; int num = 0; #region 1.被线程调用 监听连接端口 /// <summary> /// 被线程调用 监听连接端口 /// </summary> void StartWatch(Socket sokWatch) { while (isWatch) { //监听 客户端 连接请求,但是,Accept会阻断当前线程 Socket sokMsg = sokWatch.Accept();//监听到请求,立即创建负责与该客户端套接字通信的套接字 string st = sokMsg.RemoteEndPoint.ToString(); if (st != null) { string[] str = st.Split(':'); ClientIp clientIp = new ClientIp(); clientIp.Cip = str[0]; clientIp.CPort = str[1]; clientIp.stk = sokMsg; ClientIp cliIp = list.Find(i => i.Cip == clientIp.Cip && i.CPort == clientIp.CPort); if (cliIp == null) { list.Add(clientIp); isRec = true; } } this.ClientList.Items.Add(st + "于 " + DateTime.Now.ToString() + "成功连接服务器."); task = Task.Factory.StartNew(() => NewMethod(sokMsg)); } } private void NewMethod(Socket sokMsg) { while (isRec) { try { byte[] arrMsg = new byte[1024 * 1024 * 2]; //接收 对应 客户端发来的消息 int length = sokMsg.Receive(arrMsg); //将接收到的消息数组里真实消息转成字符串 if (length > 0) { string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg, 0, length); if (strMsg != null && strMsg != "") { Send(sokMsg, strMsg); } } } catch { isRec = false; } } } #endregion void Send(Socket sokMsg,string strmsg) { try { Sendmsg msg = JsonConvert.DeserializeObject<Sendmsg>(strmsg); ClientIp clientIp = list.Find(i => i.Cip == msg.OtherPartyIP && i.CPort == msg.OtherPartyPort); if (clientIp != null) { //Socket socketmsg = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ////创建 ip对象 //IPAddress address = IPAddress.Parse(msg.OtherPartyIP); ////创建网络节点对象 包含 ip和port //IPEndPoint endpoint = new IPEndPoint(address, int.Parse(msg.OtherPartyPort)); ////连接 服务端监听套接字 //socketmsg.Connect(endpoint); if (msg.msgType == 0) { string Sendinfo = JsonConvert.SerializeObject(msg); byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(Sendinfo); byte[] arrMsgFinal = new byte[arrMsg.Length + 1]; arrMsgFinal[0] = 0;//设置 数据标识位等于0,代表 发送的是 文字 arrMsg.CopyTo(arrMsgFinal, 1); clientIp.stk.Send(arrMsgFinal); } else if (msg.msgType == 2) { byte[] arrMsgFinal = new byte[1]; arrMsgFinal[0] = 2; clientIp.stk.Send(arrMsgFinal); } } else { string stmsg = "找不到目标IP"; byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(stmsg); byte[] arrMsgFinal = new byte[arrMsg.Length + 1]; string st = sokMsg.RemoteEndPoint.ToString(); string[]str= st.Split(':'); ClientIp cliIp = list.Find(i => i.Cip == str[0]); if (cliIp != null) { arrMsgFinal[0] = 0;//设置 数据标识位等于0,代表 发送的是 文字 arrMsg.CopyTo(arrMsgFinal, 1); cliIp.stk.Send(arrMsgFinal); } } } catch (Exception) { string stmsg = "服务端获取发送信息不完整无法解析"; byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(stmsg); byte[] arrMsgFinal = new byte[arrMsg.Length + 1]; arrMsgFinal[0] = 0;//设置 数据标识位等于0,代表 发送的是 文字 arrMsg.CopyTo(arrMsgFinal, 1); sokMsg.Send(arrMsgFinal); } } private void btnclose_Click(object sender, EventArgs e) { try { isWatch = false; sokWatch.Dispose(); sokWatch.Close();//关闭socket //cancelTokenSource.Cancel(); //threadWatch.();//线程终止 this.ClientList.Items.Add("服务于 " + DateTime.Now.ToString() + " 停止运行."); } catch (Exception) { sokWatch.Close();//关闭socket this.ClientList.Items.Add("服务于 " + DateTime.Now.ToString() + " 停止运行."); } } } public class ClientIp { public string Cip { get; set; } public string CPort { get; set; } public Socket stk { get; set; } } public class Sendmsg { public string OtherPartyIP { get; set; } public string OtherPartyPort { get; set; } public string Sendinfo { get; set; } public int msgType { get; set; } public byte[] msginfo { get; set; } }
ScoketService的界面
ScoketClient
public partial class Form2 : Form { //IMRichTextBox _imRichTextBox; public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { //richTextBox1.SelectedText += " 李小说: " + DateTime.Now + " "; richTextBox1.SelectionStart += richTextBox1.TextLength; richTextBox1.ScrollToCaret(); string picPath = Application.StartupPath + @"imgkeai.jpg"; Image img = Image.FromFile(picPath); Bitmap bmp = new Bitmap(picPath);//获得图片 Clipboard.SetDataObject(bmp, false);//将图片放在剪贴板中 if (richTextBox1.CanPaste(DataFormats.GetFormat(DataFormats.Bitmap))) richTextBox1.Paste(); } private void button2_Click(object sender, EventArgs e) { richTextBox1.SelectAll(); richTextBox1.Copy(); } private void button3_Click(object sender, EventArgs e) { richTextBox1.Paste(); } }
ScoketClient界面:
运行图: