using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Management;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Socket socketWatch;
public List<byte> BufferData = new List<byte>(); // 数据帧缓存空间
public FileStream writefile = null; //文件输入
private DateTime GetCurrentTime()
{
DateTime currentTime = new DateTime();
currentTime = DateTime.Now;
return currentTime;
}
void showMsg(string str)
{
txtMsg.AppendText(str + "\r\n");
}
private void button1_Click(object sender, EventArgs e)
{
socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//定义一个套接字用于监听客户端发来的信息 包含3个参数(IP4寻址协议流式连接,ICP协议)
// 服务端发送信息需要1个P地址和端口号
// IPAddress address = IPAddress.Parse(txtIp.Text.Trim());
IPAddress ip = IPAddress.Any;
// IPEndPoint endPoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));//创建终结点(EndPoint)
socketWatch.Bind(point);
showMsg("[" + DateTime.Now + "]: " + "监听成功");
socketWatch.Listen(20);
Thread th = new Thread(Listen);//新建线程,运行soketWatch(),这里的Listen是自定义的方法
th.IsBackground = true;//线程为后台属性
th.Start(socketWatch);//提供线程要执行的方法的要使用的数据(参数)的对象
btnStart.BackColor = Color.Green;
btnStart.Enabled = false;
btnStop.Enabled = true;
this.Invoke((EventHandler)delegate
{
txtMsg.AppendText("["+GetCurrentTime()+"]" + " " +"开始监听客户端传来的消息"+"\r\n");
});
}
//将远程连接的客户端的IP地址和Socket存入集合中
Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
// Socket socConnetcion = null;
Socket socketSend;
void Listen(object o)
{
Socket socketWatch = o as Socket;
while (true)
{
try
{
socketSend = socketWatch.Accept();
dic.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
txtMsg.AppendText("[" + GetCurrentTime() + "]: " + socketSend.RemoteEndPoint.ToString() + ": " + "连接成功");
comboBox1.Items.Add(socketSend.RemoteEndPoint.ToString());
Thread getdate = new Thread(GetData);
getdate.IsBackground = true;
getdate.Start(socketSend);
}
catch
{
}
}
}
private void ServerSendMsg(string sendMsg)
{
int portNum = 0;
int selectPortNum = 0;
portNum = comboBox1.Items.Count;
try
{
if ((textsendPortNum.Text != null))
{
selectPortNum = int.Parse(textsendPortNum.Text);
if (selectPortNum<= portNum)
{
comboBox1.SelectedIndex = int.Parse(textsendPortNum.Text);
}
else
{
MessageBox.Show("当前选择的端口号大于端口号最大值");
}
}
else
{
MessageBox.Show("当前选择的端口号不可为空");
}
}
catch (Exception)
{
throw;
}
// comboBox1.SelectedItem = int.Parse(textsendPortNum.Text);
if (comboBox1.SelectedItem == null)
{
MessageBox.Show("请选择客户端");
return;
}
//获取输入框输入的数据 SendHexcheckBox
byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);
string getIp = comboBox1.SelectedItem as string;
socketSend = dic[getIp] as Socket;
//this.sendMsg.Text = "";
if (SendHexcheckBox.CheckState == CheckState.Checked) //判定数据显示格式为十六进制显示
{
try
{
//sendMsg = sendMsg.Replace("0x", "").Replace(" ", ""); // 将十六进制字符串前的“0x”去掉
byte[] sendData = HexStringToByte(sendMsg); // 将字符串转换成byte字符串放入数组
//SendByte_Cnt += sendData.Length; // 修改发计数,发送数据的长度
if (sendData == null) // 判定发送的数据为空
{
MessageBox.Show("请输入数据", "提示");
}
else
{
socketSend.Send(sendData);
showMsg("[" + DateTime.Now + "]: " + "服务器发送:" + sendMsg);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
MessageBox.Show("SendData请输入以“0x00”或“00”形式输入十六进制数", "错误");
}
}
else // 直接以字符形式发送
{
try
{
// if (checknewline2.CheckState == CheckState.Checked) //判定数据显示格式为十六进制显示
{
socketSend.Send(arrSendMsg);
showMsg("[" + DateTime.Now + "]: " + "服务器发送:" + sendMsg);
}
}
catch (Exception ec)
{
MessageBox.Show("错误1:SendData2" + ec.Message, "错误"); // 异常提示信息
}
}
}
void ThreadSavDat(object o)
{
byte[] buf = o as byte[]; // 声明一个数组
if (writefile != null && writefile.CanWrite)
{
writefile.Write(buf, 0, buf.Length); // 数据写入内部缓冲区
}
}
void GetData(object socketClientPara)
{
Socket socketSend = socketClientPara as Socket;
while (true)
{
try
{
//创建一个内存缓冲区,其大小为1024*1024字节 即1M
byte[] arrServerRecMsg = new byte[1024 * 1024];
//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
int length = socketSend.Receive(arrServerRecMsg);
if (length == 0) //如果接收到的有效字节数为0 说明客户端已经关闭了。这时候就跳出循环
{
break;
}
//将机器接受到的字节数组转换为人可以读懂的字符串
//string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
if (chkbHexDisplay.CheckState == CheckState.Checked) // 判定数据显示格式为十六进制
{
byte[] buf = new byte[length]; // 声明一个临时数组存储当前串口数据
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadSavDat), buf); // 将方法排入队列
BufferData.AddRange(buf); // 串口数据写到自定义缓冲区,准备进行数据帧识别处理
string tempstr = string.Empty; // 声明一个没有分配空间的变量
for (int i = 0; i < length; i++) // 遍历缓存数据
{
tempstr += arrServerRecMsg[i].ToString("X2") + " "; // 拼接十六进制字符串
}
txtRec.AppendText(GetCurrentTime() + "FromClient:" + socketSend.RemoteEndPoint.ToString().Substring(socketSend.RemoteEndPoint.ToString().Length-2,2) + "\r\n" + tempstr + "\r\n");//追加到接收数据显示框中
}
else
{
//txtRec.AppendText(GetCurrentTime() + "FromClient:" + socketSend.RemoteEndPoint.ToString() + " " + " " + strSRecMsg + "\r\n");
txtRec.AppendText(GetCurrentTime() + "FromClient:" + socketSend.RemoteEndPoint.ToString().Substring(socketSend.RemoteEndPoint.ToString().Length - 2, 2) + "\r\n" + strSRecMsg + "\r\n");
}
}
catch (Exception ex)
{
//clientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString());
//Console.WriteLine("Client Count:" + clientConnectionItems.Count);
提示套接字监听异常
//Console.WriteLine("客户端" + socketServer.RemoteEndPoint + "已经中断连接" + "\r\n" + ex.Message + "\r\n" + ex.StackTrace + "\r\n");
关闭之前accept出来的和客户端进行通信的套接字
//socketServer.Close();
//break;
}
}
}
private void button2_Click(object sender, EventArgs e)
{
string strSendMsg = null;
if (sendcheckBox.CheckState == CheckState.Checked)
{
strSendMsg= sendMsg.Text.Trim() + "\r\n";
ServerSendMsg(strSendMsg);
}
else
ServerSendMsg(sendMsg.Text.Trim());
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
btnStart.Enabled = true;
btnStop.Enabled = false;
}
private void getLocalIpBTN_Click(object sender, EventArgs e)
{
//foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
//{
// if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
// {
// listBox1.Items.Add( _IPAddress.ToString());
// }
//}
string thisip = "";
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");//获得本机ip、掩码、网关,必须引用System.management
ManagementObjectCollection nics = mc.GetInstances();
foreach (ManagementObject nic in nics)
{
if (Convert.ToBoolean(nic["ipEnabled"]) == true)
{
thisip = (nic["IPAddress"] as String[])[0];
//thissubnet = (nic["IPSubnet"] as String[])[0];
//thisgatway = (nic["DefaultIPGateway"] as String[])[0];
}
}
this.txtLocalIp.Text = thisip;
this.txtIp.Text= thisip;
}
private void txtIp_TextChanged(object sender, EventArgs e)
{
}
// 十六进制字符串转换
private byte[] HexStringToByte(string InString)
{
//if (InString.Length % 2 != 0) // 判定字符串长度为奇数
//{
// InString = InString + "0"; // 空位补“0”
//}
//byte[] buffer = new byte[InString.Length / 2]; // 用字符串长度的一半初始化byte型数组
//for (int i = 0; i < InString.Length; i += 2)
//{
// buffer[i / 2] = (byte)Convert.ToByte(InString.Substring(i, 2), 16); // 将16进制格式的字符串强制转换成byte类型值并取指定位置的2个值存入数组
//}
//return buffer; // 返回数组
InString = InString.Replace(" ", "");
byte[] buffer = new byte[InString.Length / 2];
for (int i = 0; i < InString.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(InString.Substring(i, 2), 16);
return buffer;
}
private void btnStop_Click(object sender, EventArgs e)
{
socketWatch.Close();
}
private void btnSave2_Click(object sender, EventArgs e)
{
string sSavePath = txtbSavePath0.Text + @"\DataSave0.txt"; // 声明数据保存格式及保存路径
try
{
StreamWriter Savefile = File.CreateText(sSavePath); // 文件写入流
if (txtRec.Text != "") // 接收数据文本区数据状态判定
{
//Savefile.WriteLine(DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss")); // 保存文件当前写入时间
Savefile.WriteLine(txtRec.Text); // 接收数据文本区的数据写入保存文件
}
Savefile.Close();
}
catch (Exception ec)
{
MessageBox.Show("错误:保存按钮" + ec.Message, "错误");
}
}
private void btnClrRcv2_Click(object sender, EventArgs e)
{
txtRec.Text = string.Empty; // 清除数据接收区(Empty为不分配存储空间)
}
}
}