C#中的TCP通讯与UDP通讯
1、TCP
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Web; namespace Rdbclass { public class Rdb { ArrayList arrDatalist = new ArrayList();//存储需要发送的数据 ArrayList arrSendDataList = new ArrayList();//存储改变了值的数据 private TcpClient client;//声明TCP客户端 private ThreadStart threadStart;//声明一个线程 private Thread client_th; private string sip; private int iPort; //构造函数进行数据的初始化 public Rdb(string strip, ArrayList list, int Port) { arrDatalist = list; sip = strip; iPort = Port; connect_s(); } //连接服务器 private void connect_s() { try { client = new TcpClient(sip, iPort); threadStart = new ThreadStart(AcceptMsg); client_th = new Thread(threadStart); client_th.Start(); } catch (System.Exception ex) { throw new Exception(ex.ToString()); } } //接收数据方法,在程序运行的时候开启一个线程进行数据的接收 private void AcceptMsg() { NetworkStream ns = client.GetStream(); //字组处理 while (true) { try { byte[] bytes = new byte[4096]; byte[] sendBytes = new byte[4096]; NetworkStream sendStream1 = client.GetStream(); int bytesread = ns.Read(bytes, 0, bytes.Length); string msg = Encoding.UTF8.GetString(bytes, 0, bytesread); for (int i = 0; i < arrDatalist.Count; i++) { string strItemData = (string)arrDatalist[i]; string[] Data = strItemData.Split('|'); string[] DataReceive = msg.Split('|'); if (Data[0].ToString() == DataReceive[1].ToString() && DataReceive[0].ToString() == "val") { arrDatalist.RemoveAt(i); string strNewData = DataReceive[1] + "|" + DataReceive[2]; arrDatalist.Add(strNewData); sendBytes = Encoding.UTF8.GetBytes("ret|" + DataReceive[1] + "|ok!"); sendStream1.Write(sendBytes, 0, sendBytes.Length); sendStream1.Flush(); } } ns.Flush(); } catch (System.Exception ex) { throw new Exception(ex.ToString()); } } } private void Sendmessage() { if (client == null) return; NetworkStream sendStream = client.GetStream(); Byte[] sendBytes; if (arrSendDataList.Count > 0) { for (int i = 0; i < arrSendDataList.Count; i++) { string message = arrSendDataList[i].ToString(); arrSendDataList.RemoveAt(i); sendBytes = Encoding.UTF8.GetBytes(message); sendStream.Write(sendBytes, 0, sendBytes.Length); sendStream.Flush(); } } } //修改原始数据里面的值并发送数据 public void ModiData(string strName, string value) { try { int iCount = arrDatalist.Count; if (iCount > 0) { for (int i = 0; i < iCount; i++) { string strItemData = (string) arrDatalist[i]; string[] Data = strItemData.Split('|'); if (Data[0].ToString() == strName) { arrDatalist.RemoveAt(i); string strNewData = Data[0] + "|" + value; arrDatalist.Add(strNewData); arrSendDataList.Add("val|" + strNewData); break; } } Sendmessage(); } } catch (Exception ex) { throw new Exception(ex.ToString()); } } //退出整个应用 public void Exit() { if (client != null) { client.Close(); } } } }
2、UDP
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace TCPTest.PubHelp { public class UPDRdc { ArrayList arrDatalist = new ArrayList();//存储点表的数据 ArrayList arrSendDataList = new ArrayList();//存储改变了的值的数据 private string strSendIP;//需要发送数据的地址 private int ISendport; //发送的端口号 IPEndPoint remoteSendIpep; ArrayList arrSendlist = new ArrayList(); //11094 /// <summary> /// 用于UDP发送的网络服务类 /// </summary> private UdpClient udpcSend; public UPDRdc(ArrayList list, string SendIP, int SendPort) { arrDatalist = list; strSendIP = SendIP; ISendport = SendPort; StartRecvData();//初始化接收数据 } //初始化发送节点 private void SetSendPoint() { remoteSendIpep = new IPEndPoint( IPAddress.Parse(strSendIP), ISendport); // 发送到的IP地址和端口号 } //接收数据 /// <summary> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void StartRecvData() { SetSendPoint(); udpcSend = new UdpClient(0); } //修改原始数据里面的值并发送数据 public void ModiData(string strName, string value) { int iCount = arrDatalist.Count; if (iCount > 0) { for (int i = 0; i < iCount; i++) { string strItemData = (string)arrDatalist[i]; string[] Data = strItemData.Split(','); if (Data[0].ToString() == strName) { arrDatalist.RemoveAt(i); string strNewData = Data[0] + "," + value; arrDatalist.Add(strNewData); arrSendDataList.Add("setvardata,0;" + strNewData + ";"); break; } } NeedSendMessage(); } } //退出整个应用 public void Exit() { if (udpcSend != null) { udpcSend.Close(); } } private void NeedSendMessage() { if (arrSendDataList.Count > 0) { for (int i = 0; i < arrSendDataList.Count; i++) { string message = arrSendDataList[i].ToString(); arrSendDataList.RemoveAt(i); Thread thrSend = new Thread(SendMessage); thrSend.Start(message); Thread.Sleep(100); } } } /// <summary> /// 发送信息 /// </summary> /// <param name="obj"></param> private void SendMessage(object obj) { string message = (string)obj; byte[] sendbytes = Encoding.Default.GetBytes(message); GetDataSendMessage(sendbytes, sendbytes.Length, remoteSendIpep); } //发送数据 public void GetDataSendMessage(byte[] sendbytes, int len, IPEndPoint remoteSendIpep) { udpcSend.Send(sendbytes, len, remoteSendIpep); } //接收数据 public string GetDataRevMessage(IPEndPoint remoteSendIpep) { IPEndPoint remoteSendIpep1 = new IPEndPoint( IPAddress.Parse(strSendIP), 0); byte[] bytRecv = udpcSend.Receive(ref remoteSendIpep); string message = Encoding.Default.GetString( bytRecv, 0, bytRecv.Length); return message; } public void SendCZTest(string message) { Thread thrSend = new Thread(SendMessage); thrSend.Start(message); Thread.Sleep(100); } } }
测试:
ArrayList arrDatalist =new ArrayList(); string strSendIP = "192.168.6.135"; int ISendport = 8009; UPDRdc uPDRdc = new UPDRdc(arrDatalist, strSendIP, ISendport); uPDRdc.SendCZTest("\r\n测试试试吧!");
二、TCP客户端
页面:
代码:
public partial class SocketForm : Form { private Socket mySocket = null; public const int TCPBufferSize = 1460;//缓存的最大数据个数 public byte[] TCPBuffer = new byte[TCPBufferSize];//缓存数据的数组 public SocketForm() { InitializeComponent(); } private void SocketForm_Load(object sender, EventArgs e) { } /// <summary> /// 连接按钮点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_connect_Click(object sender, EventArgs e) { if (btn_connect.Text == "连接") { //IP地址 和 端口号输入不为空 if (string.IsNullOrEmpty(textBox1.Text) == false && string.IsNullOrEmpty(textBox2.Text) == false) { try { IPAddress ipAddress = IPAddress.Parse(textBox1.Text);//获取IP地址 int Port = Convert.ToInt32(textBox2.Text); //获取端口号 mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //使用 BeginConnect 异步连接 mySocket.BeginConnect(ipAddress, Port, new AsyncCallback(ConnectedCallback), mySocket); } catch (Exception) { MessageBox.Show("IP地址或端口号错误!", "提示"); } } else { MessageBox.Show("IP地址或端口号错误!", "提示"); } } else { try { btn_connect.Text = "连接"; mySocket.BeginDisconnect(false, null, null);//断开连接 } catch (Exception) { } } } /// <summary> /// 连接异步回调函数 /// </summary> /// <param name="ar"></param> void ConnectedCallback(IAsyncResult ar) { Socket socket = (Socket)ar.AsyncState; try { socket.EndConnect(ar); //设置异步读取数据,接收的数据缓存到TCPBuffer,接收完成跳转ReadCallback函数 socket.BeginReceive(TCPBuffer, 0, TCPBufferSize, 0, new AsyncCallback(ReadCallback), socket); Invoke((new Action(() => { txt_dataRecept.AppendText("成功连接服务器\n");//对话框追加显示数据 btn_connect.Text = "断开"; }))); } catch (Exception e) { Invoke((new Action(() => { txt_dataRecept.AppendText("连接失败:" + e.ToString());//对话框追加显示数据 }))); } } /// <接收到数据回调函数> /// /// </summary> /// <param name="ar"></param> void ReadCallback(IAsyncResult ar) { Socket socket = (Socket)ar.AsyncState;//获取链接的Socket int CanReadLen = socket.EndReceive(ar);//结束异步读取回调,获取读取的数据个数 if (CanReadLen > 0) { string str = Encoding.Default.GetString(TCPBuffer, 0, CanReadLen);//Byte值根据ASCII码表转为 String Invoke((new Action(() => //C# 3.0以后代替委托的新方法 { if (checkBox1.Checked)//16进制显示 { txt_dataRecept.AppendText(byteToHexStr(TCPBuffer, CanReadLen));//对话框追加显示数据 } else { txt_dataRecept.AppendText(Encoding.Default.GetString(TCPBuffer, 0, CanReadLen));//对话框追加显示数据 } }))); //设置异步读取数据,接收的数据缓存到TCPBuffer,接收完成跳转ReadCallback函数 socket.BeginReceive(TCPBuffer, 0, TCPBufferSize, 0, new AsyncCallback(ReadCallback), socket); } else//异常 { Invoke((new Action(() => //C# 3.0以后代替委托的新方法 { btn_connect.Text = "连接"; txt_dataRecept.AppendText("\n异常断开\n");//对话框追加显示数据 }))); try { mySocket.BeginDisconnect(false, null, null);//断开连接 } catch (Exception) { } } } /// <summary> /// 发送 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_send_Click(object sender, EventArgs e) { String Str = txt_dataSend.Text.ToString();//获取发送文本框里面的数据 try { if (Str.Length > 0) { if (checkBox2.Checked)//选择16进制发送 { byte[] byteHex = strToToHexByte(Str); mySocket.BeginSend(byteHex, 0, byteHex.Length, 0, null, null); //发送数据 } else { byte[] byteArray = Encoding.Default.GetBytes(Str);//Str 转为 Byte值 mySocket.BeginSend(byteArray, 0, byteArray.Length, 0, null, null); //发送数据 } } } catch (Exception) { } } /// <summary> /// 清除接收 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_clearAccept_Click(object sender, EventArgs e) { txt_dataRecept.Clear(); } /// <summary> /// 清除发送 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_clearSend_Click(object sender, EventArgs e) { txt_dataSend.Clear(); } #region 进制转换 /// <字节数组转16进制字符串> /// <param name="bytes"></param> /// <returns> String 16进制显示形式</returns> public static string byteToHexStr(byte[] bytes,int Len) { string returnStr = ""; try { if (bytes != null) { for (int i = 0; i < Len; i++) { returnStr += bytes[i].ToString("X2"); returnStr += " ";//两个16进制用空格隔开,方便看数据 } } return returnStr; } catch (Exception) { return returnStr; } } /// <字符串转16进制格式,不够自动前面补零> /// /// </summary> /// <param name="hexString"></param> /// <returns></returns> private static byte[] strToToHexByte(String hexString) { int i; hexString = hexString.Replace(" ", "");//清除空格 if ((hexString.Length % 2) != 0)//奇数个 { byte[] returnBytes = new byte[(hexString.Length + 1) / 2]; try { for (i = 0; i < (hexString.Length - 1) / 2; i++) { returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } returnBytes[returnBytes.Length - 1] = Convert.ToByte(hexString.Substring(hexString.Length - 1, 1).PadLeft(2, '0'), 16); } catch { MessageBox.Show("含有非16进制字符", "提示"); return null; } return returnBytes; } else { byte[] returnBytes = new byte[(hexString.Length) / 2]; try { for (i = 0; i < returnBytes.Length; i++) { returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } } catch { MessageBox.Show("含有非16进制字符", "提示"); return null; } return returnBytes; } } #endregion }
测试结果:
转载:https://www.cnblogs.com/wustjz/p/4650965.html
作者:chenze 出处:https://www.cnblogs.com/chenze-Index/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出。以免更多的人被误导。 |