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("启动服务器成功......\r\n");
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 += "\n李小说:\t" + DateTime.Now + "\n";
richTextBox1.SelectionStart += richTextBox1.TextLength;
richTextBox1.ScrollToCaret();
string picPath = Application.StartupPath + @"\img\keai.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界面:
运行图: