以前没搞过Socket,今天有时间就看了一下,随便写了个小demo,只实现了基本功能,一个client,一个server,很多东西没有考虑,代码也没有加工,仅供以后学习参考。
Client
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;namespace SocketClient{ public partial class Form1 : Form { private SynchronizationContext uiContext; private Socket client; private bool ConnStatus = false; private Thread showMsg; public Form1() { InitializeComponent(); } private void btnConn_Click(object sender, EventArgs e) { string ip = this.txtIP.Text; int port = Convert.ToInt32(this.txtPort.Text); IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ip), port); client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { client.Connect(ie); if (client.Connected) { this.lbStatus.Text = "Connecting..."; this.lbStatus.ForeColor = Color.Green; ConnStatus = true; uiContext = SynchronizationContext.Current; //单独起一个线程用于刷Message。 showMsg = new Thread(new ThreadStart(ShowMessage)); showMsg.Start(); this.txtSend.Enabled = true; this.btnSend.Enabled = true; } } catch { this.lbStatus.Text = "Connect Error"; this.lbStatus.ForeColor = Color.Red; } } private void ShowMessage() { byte[] data = new byte[1024]; int recv; //如果连接可以,轮询接收Message并显示在文本框 while (ConnStatus) { recv = client.Receive(data); string msg = Encoding.Unicode.GetString(data, 0, recv); //Server一旦关闭,会自动发一个exit。Client接收到之后自动关闭。 if (msg == "exit") { client.Shutdown(SocketShutdown.Both); client.Close(); ConnStatus = false; this.lbStatus.Text = "Disconnect"; txtSend.Enabled = false; btnSend.Enabled = false; msg = "Server is offline"; } //将Message显示在文本框 uiContext.Send((state) => { rtxtMsg.AppendText(DateTime.Now.ToString() + " <----" + "\n"); rtxtMsg.AppendText(msg + "\n"); int msglength = rtxtMsg.Text.Length; rtxtMsg.Select(msglength - msg.Length - 1, msg.Length); rtxtMsg.SelectionColor = Color.Red; }, null); } } private void btnSend_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txtSend.Text)) { client.Send(Encoding.Unicode.GetBytes(txtSend.Text)); rtxtMsg.AppendText(DateTime.Now.ToString() + " ---->" + "\n"); rtxtMsg.AppendText(txtSend.Text + "\n"); int msglength = rtxtMsg.Text.Length; rtxtMsg.Select(msglength - txtSend.Text.Length - 1, txtSend.Text.Length); rtxtMsg.SelectionColor = Color.Blue; txtSend.Text = string.Empty; } } private void btnDisconn_Click(object sender, EventArgs e) { ConnStatus = false; try { //Client断开连接,会先发送exit给server通知。 client.Send(Encoding.Unicode.GetBytes("exit")); client.Shutdown(SocketShutdown.Both); client.Close(); ConnStatus = false; this.lbStatus.Text = "Disconnect"; txtSend.Enabled = false; btnSend.Enabled = false; if (showMsg.IsAlive) { showMsg.Abort(); } } catch { } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //窗口关闭时断开所有链接。 if (client != null && client.Connected) { client.Shutdown(SocketShutdown.Both); client.Close(); } Environment.Exit(0); } }}
Server
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.Threading;using System.Net.Sockets;using System.Net;namespace SocketServer{ public partial class Form1 : Form { private Socket server; private Socket client; private bool clientStatus = false; private SynchronizationContext uiContext; private Thread waitConn; public Form1() { InitializeComponent(); InitSocketServer(); } private void InitSocketServer() { server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ip = new IPEndPoint(IPAddress.Any, 9050); server.Bind(ip); server.Listen(5); uiContext = SynchronizationContext.Current; } private void btnStart_Click(object sender, EventArgs e) { //单独一个线程等待接收Client连接。 waitConn = new Thread(new ThreadStart(WaitClient)); waitConn.Start(); btnStart.Enabled = false; } private void WaitClient() { client = server.Accept(); byte[] data = new byte[1024]; string welcome = "Welcome here!"; data = Encoding.Unicode.GetBytes(welcome); client.Send(data); clientStatus = true; uiContext.Send((state) => { rtxtMsg.AppendText(DateTime.Now.ToString() + " ---->" + "\n"); rtxtMsg.AppendText(welcome + "\n"); rtxtMsg.Select(rtxtMsg.Text.Length - welcome.Length - 1, welcome.Length); rtxtMsg.SelectionColor = Color.Blue; txtSend.Enabled = true; btnSend.Enabled = true; }, null); //接到连接后起一个线程接收Message. Thread showMsg = new Thread(new ParameterizedThreadStart(ShowMessage)); showMsg.Start(client); } private void ShowMessage(object client) { byte[] data = new byte[1024]; Socket newClient = (Socket)client; int recv; string msg; //连接状态下循环接收Message. while (clientStatus) { recv = newClient.Receive(data); msg = Encoding.Unicode.GetString(data, 0, recv); //Client断开连接前会发exit作为通知。 if (msg == "exit") { clientStatus = false; newClient.Shutdown(SocketShutdown.Both); newClient.Close(); msg = "Client is offline"; } uiContext.Send((state) => { rtxtMsg.AppendText(DateTime.Now.ToString() + " <----" + "\n"); rtxtMsg.AppendText(msg + "\n"); rtxtMsg.Select(rtxtMsg.Text.Length - msg.Length - 1, msg.Length); rtxtMsg.SelectionColor = Color.Red; }, null); } uiContext.Send((state) => { txtSend.Enabled = false; btnSend.Enabled = false; btnStart.Enabled = true; }, null); } private void btnSend_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txtSend.Text)) { byte[] msg = new byte[1024]; msg = Encoding.Unicode.GetBytes(txtSend.Text); client.Send(msg); rtxtMsg.AppendText(DateTime.Now.ToString() + " ---->" + "\n"); rtxtMsg.AppendText(txtSend.Text + "\n"); rtxtMsg.Select(rtxtMsg.Text.Length - txtSend.Text.Length - 1, txtSend.Text.Length); rtxtMsg.SelectionColor = Color.Blue; txtSend.Text = string.Empty; } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //关闭窗口时断开所有链接。 if (client != null && client.Connected) { client.Send(Encoding.Unicode.GetBytes("exit")); client.Shutdown(SocketShutdown.Both); client.Close(); } if (server != null) { server.Close(); } Environment.Exit(0); } }}