1.Server
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Server
{
public partial class Server_Form : Form
{
// 负责监听客户端的套接字
Socket socket_TCP = null;
// 负责和客户端通信的套接字
Socket socket_Communication = null;
//监听线程
Thread thread_Listen = null;
//客户端 端口号集合
Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
public Server_Form()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void button_Connection_Click(object sender, EventArgs e)
{
if (button_Connection.Text == "连接")
{
button_Connection.Text = "断开";
socket_TCP = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(textBox_IP.Text), (int)numericUpDown_Port.Value);
socket_TCP.Bind(iPEndPoint);
socket_TCP.Listen(0);
thread_Listen = new Thread(TCP_Listen);
thread_Listen.IsBackground = true;
thread_Listen.Start();
}
else if (button_Connection.Text == "断开")
{
button_Connection.Text = "连接";
if (socket_Communication != null)
{
socket_Communication.Close();
}
}
}
private void TCP_Listen()
{
while (true)
{
try
{
socket_Communication = socket_TCP.Accept();
//客户端网络节点
string RemoteEndPoint = socket_Communication.RemoteEndPoint.ToString();
dic.Add(RemoteEndPoint, socket_Communication);
listBoxOnlineList.Items.Add(RemoteEndPoint);
//传参的线程
ParameterizedThreadStart pts = new ParameterizedThreadStart(TCP_Read);
Thread thread = new Thread(pts);
thread.IsBackground = true;
thread.Start(socket_Communication);
}
catch (Exception e)
{
break;
}
}
}
private void button_Send_Click(object sender, EventArgs e)
{
if (listBoxOnlineList.SelectedIndex == -1)
{
MessageBox.Show("请选择要发送的客户端!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
else
{
string selectClient = listBoxOnlineList.Text;
TCP_Write(textBox_Send.Text, selectClient);
textBox_Send.Text = "";
}
}
//获取当前系统时间
private DateTime GetCurrentTime()
{
DateTime currentTime = new DateTime();
currentTime = DateTime.Now;
return currentTime;
}
private void TCP_Write(string data, string EndPoint)
{
try
{
//byte[] arrClientSendMsg = new byte[] { 0x11, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC6, 0x9B };
byte[] arrClientSendMsg = HexStringToByteArray(data);
dic[EndPoint].Send(arrClientSendMsg);
richTextBox_Receive.AppendText("本机: " + GetCurrentTime() + "\r\n" + data + "\r\n\n");
//dic[EndPoint].Send(Encoding.UTF8.GetBytes(data));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
}
private void TCP_Read(object socket_Read)
{
Socket socket = socket_Read as Socket;
while (true)
{
try
{
byte[] buffer_Data = new byte[1024 * 1024];
int Accept_length = socket.Receive(buffer_Data);
List<string> resultArr = new List<string> { };
EndPoint endPoint = socket.RemoteEndPoint;
/* if (buffer_Data != null && buffer_Data[0] != 0 && buffer_Data[0] != 11)
{
byte[] arr = buffer_Data.Skip(0).Take(100).ToArray();
//byte转16
string strRevMsg = byteToHexStr(arr);
richTextBox_Receive.AppendText("客户端 " + endPoint + ":" + strRevMsg + "\r\n");
}*/
//buffer_Data[0] == 11时为485温湿度ID17的返回值
//S723型电压电流表的数据处理
if (buffer_Data != null && buffer_Data[0] != 0 && buffer_Data[0] != 11)
{
byte[] arr = buffer_Data.Skip(0).Take(100).ToArray();
for(int i = 3;i< arr.Length && arr[i] != 0;)
{
byte[] floatArr = arr.Skip(i).Take(4).ToArray();
string s = byteToHexStr(floatArr);
//string转float
MatchCollection matches = Regex.Matches(s, @"[0-9A-Fa-f]{2}");
byte[] bytes = new byte[matches.Count];
for (int j = 0; j < bytes.Length; j++)
bytes[j] = byte.Parse(matches[j].Value, System.Globalization.NumberStyles.AllowHexSpecifier);
float m = BitConverter.ToSingle(bytes.Reverse().ToArray(), 0);、
//保留两位小数
string number = m.ToString("0.00");
//resultArr对应最终数据的数组,插入数据库即可
resultArr.Add(number);
i = i + 4;
}
richTextBox_Receive.AppendText("客户端 " + endPoint + ":" + /*resultArr*/"电压电流数据读取成功" + "\r\n");
}
}
catch (Exception)
{
//提示套接字监听异常
richTextBox_Receive.AppendText("客户端" + socket.RemoteEndPoint + "已经中断连接" + "\r\n");
//移除断开的客户端
dic.Remove(socket.RemoteEndPoint.ToString());
//从listbox中移除断开连接的客户端
listBoxOnlineList.Items.Remove(socket.RemoteEndPoint.ToString());
//关闭之前accept出来的和客户端进行通信的套接字
socket_Communication.Close();
break;
}
}
}
private void richTextBox_Receive_TextChanged(object sender, EventArgs e)
{
}
/// <summary>
///16进制string类型转数组
/// </summary>
public static byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
/// <summary>
///数组转16/10进制字符串
/// </summary>
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
//转10进制
//returnStr += Convert.ToInt32(bytes[i]);
//转16进制
returnStr += bytes[i].ToString("X2");//ToString("X2") 转化为大写的16进制
//returnStr = returnStr + " ";
}
}
return returnStr;
}
/// <summary>
///十六进制转为float
/// </summary>
public static float ToFloat(byte[] data)
{
float a = 0;
byte i;
byte[] x = data;
unsafe
{
void* pf;
fixed (byte* px = x)
{
pf = &a;
for (i = 0; i < data.Length; i++)
{
*((byte*)pf + i) = *(px + i);
}
}
}
return a;
}
/// <summary>
/// float转为十六进制
/// </summary>
public static byte[] ToByte(float data)
{
unsafe
{
byte* pdata = (byte*)&data;
byte[] byteArray = new byte[sizeof(float)];
for (int i = 0; i < sizeof(float); ++i)
byteArray[i] = *pdata++;
return byteArray;
}
}
}
}
2.Client
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//关闭对文本框的非法线程操作检查
TextBox.CheckForIllegalCrossThreadCalls = false;
}
//创建 1个客户端套接字 和1个负责监听服务端请求的线程
Thread threadclient = null;
Socket socketclient = null;
List<IPEndPoint> mlist = new List<IPEndPoint>();
private void btnConnect_Click(object sender, EventArgs e)
{
//SocketException exception;
this.btnConnect.Enabled = false;
//定义一个套接字监听
socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取文本框中的IP地址
IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
//将获取的IP地址和端口号绑定在网络节点上
IPEndPoint point = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
try
{
//客户端套接字连接到网络节点上,用的是Connect
socketclient.Connect(point);
}
catch (Exception)
{
//MessageBox.
MessageBox.Show("连接失败\r\n");
this.btnConnect.Enabled = true;
return;
}
threadclient = new Thread(recv);
threadclient.IsBackground = true;
threadclient.Start();
}
// 接收服务端发来信息的方法
private void recv()//
{
int x = 0;
while (true)//持续监听服务端发来的消息
{
try
{
//定义一个1M的内存缓冲区,用于临时性存储接收到的消息
byte[] arrRecvmsg = new byte[1024 * 1024];
//将客户端套接字接收到的数据存入内存缓冲区,并获取长度
int length = socketclient.Receive(arrRecvmsg);
//将套接字获取到的字符数组转换为人可以看懂的字符串
//string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
//if(strRevMsg != "")
if (arrRecvmsg != null && arrRecvmsg[8] != 0)
{
//字节太长响应过慢,截取部分
byte[] arr = arrRecvmsg.Skip(0).Take(100).ToArray();
//byte转16
string strRevMsg = byteToHexStr(arr);
if (x == 1)
{
txtRecv.AppendText("服务器:" + GetCurrentTime() + "\r\n" + strRevMsg + "\r\n\n");
}
else
{
txtRecv.AppendText(strRevMsg + "\r\n\n");
x = 1;
}
}
}
catch (Exception ex)
{
//txtRecv.AppendText("远程服务器已经中断连接" + "\r\n");
this.btnConnect.Enabled = true;
break;
}
}
}
//获取当前系统时间
private DateTime GetCurrentTime()
{
DateTime currentTime = new DateTime();
currentTime = DateTime.Now;
return currentTime;
}
//发送字符信息到服务端的方法
private void ClientSendMsg(string sendMsg)
{
//byte[] arrClientSendMsg = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8b, 0x03, 0x00, 0xc8, 0x00, 0x20};
//将输入的内容字符串转换为机器可以识别的字节数组
byte[] arrClientSendMsg = HexStringToByteArray(sendMsg);
//byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
//调用客户端套接字发送字节数组
socketclient.Send(arrClientSendMsg);
//将发送的信息追加到聊天内容文本框中
txtRecv.AppendText(this.txtRecv.Text + "本机: " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n\n");
}
private void btnSend_Click(object sender, EventArgs e)
{
txtRecv.Clear();
//调用ClientSendMsg方法 将文本框中输入的信息发送给服务端
ClientSendMsg(txtSend.Text.Trim());
//txtSend.Clear();
}
private void txtSend_KeyDown(object sender, KeyEventArgs e)
{
//当光标位于文本框时 如果用户按下了键盘上的Enter键
if (e.KeyCode == Keys.Enter)
{
//则调用客户端向服务端发送信息的方法
ClientSendMsg(txtSend.Text.Trim());
txtSend.Clear();
}
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult result = MessageBox.Show("是否退出?选否,最小化到托盘", "操作提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
if (threadclient != null)
{
threadclient.Abort();
}
Thread.Sleep(500);
if (socketclient == null)
{
this.Dispose();
}
else
{
socketclient.Close();
this.Dispose();
}
}
else if (result == DialogResult.Cancel)
{
e.Cancel = true;
}
else
{
e.Cancel = true;
this.WindowState = FormWindowState.Minimized;
this.Visible = false;
//this.notifyIcon1.Visible = true;
this.ShowInTaskbar = false;
}
}
//字符串转16进制
public static byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
//十六进制转换为字符串
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
//转10进制
returnStr += Convert.ToInt32(bytes[i]);
//转16进制
//returnStr += bytes[i].ToString("X2");//ToString("X2") 转化为大写的16进制
returnStr = returnStr + " ";
}
int a = 1;
}
return returnStr;
}
}
}
暂时还没添加数据库