socket通信,tcp,udp通信

通过c#编写的一个简单的socket通信测试工具,可用于测试TCP、UDP通信,可实现基本的聊天和文件发送等功能

参考:http://blog.csdn.net/chwei_cson/article/details/7737766


TCP服务端代码



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;
using System.IO;
using System.Diagnostics;


namespace listen
{
    public partial class tcpListen : Form
    {
        Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
        Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
        private static int clientNum = 0;
        Socket[] socConnection = new Socket[65535];

        Thread threadWatch = null; // 负责监听客户端连接请求的 线程; 
        Socket socketWatch = null;
        IPEndPoint localEP = null;

        public tcpListen()
        {
            InitializeComponent();
            //this.ControlBox = false;   // 设置不出现关闭按钮
        }

        private void tcpListen_Load(object sender, EventArgs e)
        {
            if (this.DesignMode == false)
            {
                txtIP.SelectedIndex = 0;
                IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());
                foreach (IPAddress ip in ipHostEntry.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {//筛选IPV4
                        txtIP.Items.Add(ip.ToString());
                    }
                }
            }
        }
         /// <summary>
         /// 接受客户端消息并发送消息
         /// </summary>
         /// <param name="socketClientPara"></param>
         private void btnListen_Click(object sender, EventArgs e)
         {
             //txtPort.Text = "89";
             // 创建负责监听的套接字,注意其中的参数;  
             socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
             this.Invoke((EventHandler)delegate
             {
                 if (txtIP.SelectedIndex == 0)
                 {
                     localEP = new IPEndPoint(IPAddress.Any, Convert.ToInt32(txtPort.Text.Trim()));
                 }
                 else
                 {
                     localEP = new IPEndPoint(IPAddress.Parse(txtIP.Text), Convert.ToInt32(txtPort.Text.Trim()));
                 }
             });

             try
             {
                 // 将负责监听的套接字绑定到唯一的ip和端口上;  
                 socketWatch.Bind(localEP);
             }
             catch (SocketException se)
             {
                 MessageBox.Show("异常:" + se.Message);
                 return;
             }
             // 设置监听队列的长度;  
             socketWatch.Listen(10);
             // 创建负责监听的线程;  
             threadWatch = new Thread(WatchConnecting);
             threadWatch.IsBackground = true;
             threadWatch.Start();
             ShowMsg(Convert.ToString(localEP) + "服务器启动监听成功!"+"\r\n"+"等待客户端连接!");
         }

         /// <summary>  
         /// 监听客户端请求的方法;  
         /// </summary>  
         void WatchConnecting()
         {
             while (true)  // 持续不断的监听客户端的连接请求;  
             {
                 // 开始监听客户端连接请求,Accept方法会阻断当前的线程;  
                 socConnection[clientNum] = socketWatch.Accept();

                 this.Invoke((EventHandler)delegate
                 {
                     // 想列表控件中添加客户端的IP信息;  
                     lbOnline.Items.Add(socConnection[clientNum].RemoteEndPoint.ToString());
                     // 将与客户端连接的 套接字 对象添加到集合中;  
                     dict.Add(socConnection[clientNum].RemoteEndPoint.ToString(), socConnection[clientNum]);
                     ShowMsg(socConnection[clientNum].RemoteEndPoint.ToString() + "客户端连接成功!");

                     string temp = socConnection[clientNum].RemoteEndPoint.ToString() + "连接成功";
                     byte[] mesg = System.Text.Encoding.UTF8.GetBytes(temp); // 将要发送的字符串转换成Utf-8字节数组;
                     socConnection[clientNum].Send(mesg);
                 });

                 Thread thread = new Thread(new ParameterizedThreadStart(RecMsg));
                 thread.IsBackground = true;
                 thread.Start(socConnection[clientNum]);
                 dictThread.Add(socConnection[clientNum].RemoteEndPoint.ToString(), thread);  //  将新建的线程 添加 到线程的集合中去。  
                 clientNum++;

             }
         }
       
         void RecMsg(object sokConnectionparn)
         {
             Socket socketServer = sokConnectionparn as Socket;
             while (true)
             {
                 // 定义一个2M的缓存区;  
                 byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                 // 将接受到的数据存入到输入  arrMsgRec中;  
                 int length = -1;
                 try
                 {
                     length = socketServer.Receive(arrMsgRec); // 接收数据,并返回数据的长度;  
                 }
                 catch (SocketException se)
                 {
                     // 从 通信套接字 集合中删除被中断连接的通信套接字;  
                     dict.Remove(socketServer.RemoteEndPoint.ToString());
                     // 从通信线程集合中删除被中断连接的通信线程对象;  
                     dictThread.Remove(socketServer.RemoteEndPoint.ToString());
                     this.Invoke((EventHandler)delegate
                     {
                         // 从列表中移除被中断的连接IP  
                         lbOnline.Items.Remove(socketServer.RemoteEndPoint.ToString());
                         ShowMsg("异常1:" + se.Message);
                     });
                     break;
                 }
                 catch (Exception e)
                 {
                     // 从 通信套接字 集合中删除被中断连接的通信套接字;  
                     dict.Remove(socketServer.RemoteEndPoint.ToString());
                     // 从通信线程集合中删除被中断连接的通信线程对象;  
                     dictThread.Remove(socketServer.RemoteEndPoint.ToString());
                     this.Invoke((EventHandler)delegate
                     {
                         ShowMsg("异常2:" + e.Message);
                         // 从列表中移除被中断的连接IP  
                         lbOnline.Items.Remove(socketServer.RemoteEndPoint.ToString());
                     });
                     break;
                 }
                 if (arrMsgRec[0] == 0)  // 表示接收到的是数据;  
                 {
                     this.Invoke((EventHandler)delegate
                     {
                         string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length-1 );// 将接受到的字节数据转化成字符串;  
                         this.showinfo.Text += "客户端" + socketServer.RemoteEndPoint.ToString() + "-->" + strMsg+"\r\n";

                     });
                 }
                 if (arrMsgRec[0] == 1) // 表示接收到的是文件;  
                 {
                     SaveFileDialog sfd = new SaveFileDialog();
                     sfd.Filter = "所有文件(*.* )|*.*";
                     this.Invoke((EventHandler)delegate
                     {
                         if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                         {// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】  

                             string fileSavePath = sfd.FileName;// 获得文件保存的路径;  
                             // 创建文件流,然后根据路径创建文件;  
                             using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
                             {
                                 fs.Write(arrMsgRec, 1, length - 1);
                                 //fs.Write(arrMsgRec, 0, length);
                                 ShowMsg("文件保存成功:" + fileSavePath + "\r\n");
                                 fs.Flush();
                                 fs.Close();
                             }
                         }
                     });
                 }
             }
         }
         void ShowMsg(string str)
         {
             this.Invoke((EventHandler)delegate
             {
                 txtInfo.AppendText(str + "\r\n");
             });
         }

         private void btnSend_Click(object sender, EventArgs e)
         {
             string strMsg = "服务器"+Convert.ToString(localEP)+"-->" + txtMsgSend.Text.Trim();
             byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;  
             byte[] arrSendMsg = new byte[arrMsg.Length + 1];
             arrSendMsg[0] = 0; // 表示发送的是消息数据  
             Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
             string strKey = "";

             strKey = txtCl.Text.Trim();
             if (string.IsNullOrEmpty(strKey) || strKey == "客户端")   // 判断是不是选择了发送的对象;  
             {
                 MessageBox.Show("请选择你要发送的客户端!!!");
             }
             else
             {
                 dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题; 
                 showinfo.AppendText(strMsg + "\r\n");
                 //txtMsgSend.Clear();
             } 
         }

         private void lbOnline_SelectedIndexChanged(object sender, EventArgs e)
         {
             try
             {
                 txtCl.Text = lbOnline.SelectedItem.ToString().Trim();
             }
             catch (Exception ex)
             { }
         }

         private void txtInfo_TextChanged(object sender, EventArgs e)
         {
             //选择richtextbox中内容的最后一个字节            
             this.txtInfo.Select(this.txtInfo.Text.Length, 1);
             //设置滚动到当前位置
             this.txtInfo.ScrollToCaret();
         }

         private void showinfo_TextChanged(object sender, EventArgs e)
         {
             //选择richtextbox中内容的最后一个字节            
             this.showinfo.Select(this.showinfo.Text.Length, 1);
             //设置滚动到当前位置
             this.showinfo.ScrollToCaret();
         }

         private void btnSendToAll_Click(object sender, EventArgs e)
         {
             string strMsg = "服务器"+Convert.ToString(localEP)+   "-->" + txtMsgSend.Text.Trim();  
             byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;  
             byte[] arrSendMsg = new byte[arrMsg.Length + 1]; // 用来标识发送是数据而不是文件,如果没有这一段的客户端就接收不到消息了~~~  
             arrSendMsg[0] = 0; // 表示发送的是消息数据  
             Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
             foreach (Socket s in dict.Values)
             {
                 s.Send(arrSendMsg);
             }
             ShowMsg(strMsg);
             //txtMsgSend.Clear();
         }

         private void btnSendFile_Click(object sender, EventArgs e)
         {
             OpenFileDialog ofd = new OpenFileDialog();
             ofd.Filter = "所有文件(*.* )|*.*";
             ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
             string filePath = "";
             if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
             {
                 filePath = ofd.FileName;
             }

             if (string.IsNullOrEmpty(filePath))  
            {  
                MessageBox.Show("请选择你要发送的文件!!!");  
            }  
            else  
            {  
                // 用文件流打开用户要发送的文件;  
                using (FileStream fs = new FileStream(filePath, FileMode.Open))  
                {
                    string fileName = System.IO.Path.GetFileName(filePath);
                    string fileExtension = System.IO.Path.GetExtension(filePath);
                    string strMsg = "服务器" + Convert.ToString(localEP) + "给你发送的文件为: " + fileName + "\r\n";  
                    byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;  
                    byte[] arrSendMsg = new byte[arrMsg.Length + 1];  
                    arrSendMsg[0] = 0; // 表示发送的是消息数据  
                    Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);  
                    string strKey = "";  
                    strKey = lbOnline.Text.Trim();  
                    if (string.IsNullOrEmpty(strKey))   // 判断是不是选择了发送的对象;  
                    {  
                        MessageBox.Show("请选择你要发送的客户端!!!");  
                    }  
                    else  
                    {  
                    dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;先发送文件名  

                    byte[] arrFile = new byte[1024 * 1024 * 2];  
                    int length = fs.Read(arrFile, 0, arrFile.Length);  // 将文件中的数据读到arrFile数组中;  
                    byte[] arrFileSend = new byte[length +1];  
                    arrFileSend[0] = 1; // 用来表示发送的是文件数据;  
                    Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);  
                    // 还有一个 CopyTo的方法,但是在这里不适合; 当然还可以用for循环自己转化;  
                    //  sockClient.Send(arrFileSend);// 发送数据到服务端;  
                    dict[strKey].Send(arrFileSend);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;  
                       //txtSelectFile.Clear();   
                    }  
                }  
            }
             filePath="";  
            
         }

         private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
         {
             tcpListen fi = new tcpListen();
             fi.Show();
         }

         private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
         {
             tcpClient fi = new tcpClient();
             fi.Show();
         }

         private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
         {
             udpServer fi = new udpServer();
             fi.Show();
         }

         private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
         {
             udpClient fi = new udpClient();
             fi.Show();
         }

         private void btnClose_Click(object sender, EventArgs e)
         {
             this.Close();
         }
    }
}


TCP客户端代码


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;
using System.IO; 

namespace listen
{
    public partial class tcpClient : Form
    {
        public Socket newclient;
        public bool Connected;
        public Thread myThread;
        public delegate void MyInvoke(string str);
 
        public tcpClient()
        {
            InitializeComponent();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] data = new byte[1024];
                newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                string ip = txtServerIP.Text.Trim();
                int port = Convert.ToInt32(txtServerPort.Text.Trim());
                IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ip), port);

                newclient.Connect(ie);
                //connect.Enabled = false;
                Connected = true;

            }
            catch (SocketException ex)
            {
                MessageBox.Show("连接服务器失败    " + ex.Message);
                return;
            }
            ThreadStart myThreaddelegate = new ThreadStart(ReceiveMsg);
            myThread = new Thread(myThreaddelegate);
            myThread.IsBackground = true;
            myThread.Start();
        }
        public void ReceiveMsg()
        {
            while (true)
            {
                // 定义一个2M的缓存区;  
                byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                // 将接受到的数据存入到输入  arrMsgRec中;  
                int length = -1;
                try
                {
                    length = newclient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;  
                }
                catch (SocketException se)
                {
                    showMsg("异常1;" + se.Message);
                    return;
                }
                catch (Exception e)
                {
                    showMsg("异常2:" + e.Message);
                    return;
                }
                if (arrMsgRec[0] == 0) // 表示接收到的是消息数据;  arrMsgRec[0] == 0)
                {
                    string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length - 1);// 将接受到的字节数据转化成字符串;   
                    showMsg(strMsg);
                }

                if (arrMsgRec[0] == 1) // 表示接收到的是文件数据;  
                {
                    string SaveFileName = string.Empty;
                    try
                    {
                        SaveFileDialog sfd = new SaveFileDialog();
                        sfd.Filter = "所有文件(*.* )|*.*";
                        sfd.RestoreDirectory = true;
                        sfd.Title = "Where do you want to save the file?";
                        sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

                        this.Invoke((EventHandler)delegate
                        {
                            if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                            {// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】  

                                string fileSavePath = sfd.FileName;// 获得文件保存的路径;  
                                // 创建文件流,然后根据路径创建文件;  
                                using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
                                {
                                    fs.Write(arrMsgRec, 1, length-1);
                                    fs.Flush();
                                    fs.Close();
                                }                              
                                showMsg("文件保存成功:" + fileSavePath);                       
                            }

                      
                        });
                    }
                    catch (Exception aaa)
                    {
                        MessageBox.Show(aaa.Message);
                        if (myThread != null)
                        {
                            myThread.Abort();
                        }
                        break;
                    }
                }

            }
        }
        public void showMsg(string msg)
        {
            {
                try
                {
                    //在线程里以安全方式调用控件
                    if (txtReceiveMsg.InvokeRequired)
                    {
                        MyInvoke _myinvoke = new MyInvoke(showMsg);
                        txtReceiveMsg.Invoke(_myinvoke, new object[] { msg });
                    }
                    else
                    {
                        txtReceiveMsg.AppendText(msg + "\r\n");
                    }


                }
                catch (Exception ex)
                { }

            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {

                string strMsg = txtSend.Text.Trim();
                byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
                byte[] arrSendMsg = new byte[arrMsg.Length + 1];
                arrSendMsg[0] = 0; // 用来表示发送的是消息数据  
                Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
                newclient.Send(arrSendMsg); // 发送消息;  
                showMsg("我说:" + txtSend.Text);

            }
            catch (Exception ex)
            { }
        }

        private void txtReceiveMsg_TextChanged(object sender, EventArgs e)
        {
            //选择richtextbox中内容的最后一个字节            
            this.txtReceiveMsg.Select(this.txtReceiveMsg.Text.Length, 1);
            //设置滚动到当前位置
            this.txtReceiveMsg.ScrollToCaret();
        }

        private void tcpClient_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (myThread != null)
            {
                myThread.Abort();
            }
        }

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "所有文件(*.* )|*.*";
            ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string filePath = "";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                filePath = ofd.FileName;
            }

            if (string.IsNullOrEmpty(filePath))
            {
                MessageBox.Show("请选择你要发送的文件!!!");
            }
            else
            {
                // 用文件流打开用户要发送的文件;  
                using (FileStream fs = new FileStream(filePath, FileMode.Open))
                {
                    string fileName = System.IO.Path.GetFileName(filePath);
                    string fileExtension = System.IO.Path.GetExtension(filePath);
                    string strMsg = "发送文件: " + fileName + "\r\n";
                    byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;  
                    byte[] arrSendMsg = new byte[arrMsg.Length + 1];
                    arrSendMsg[0] = 0; // 表示发送的是消息数据  
                    Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
                    newclient.Send(arrMsg); // 发送消息;  

                    byte[] arrFile = new byte[1024 * 1024 * 2];
                    int length = fs.Read(arrFile, 0, arrFile.Length);  // 将文件中的数据读到arrFile数组中;  
                    byte[] arrFileSend = new byte[length + 1];
                    arrFileSend[0] = 1; // 用来表示发送的是文件数据;  
                    Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
                    // 还有一个 CopyTo的方法,但是在这里不适合; 当然还可以用for循环自己转化;  
                    newclient.Send(arrFileSend);// 发送数据到服务端;  

                    showMsg("我发送文件:" + filePath);

                    filePath = "";
                }
            }
        }

        private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcpListen fi = new tcpListen();
            fi.Show();
        }

        private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcpClient fi = new tcpClient();
            fi.Show();
        }

        private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            udpServer fi = new udpServer();
            fi.Show();
        }

        private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
        {
            udpClient fi = new udpClient();
            fi.Show();
        }
    }
}


UDP服务端代码

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;
using System.IO;
using System.Diagnostics;

namespace listen
{
    public partial class udpServer : Form
    {
        Dictionary<string, EndPoint> dict = new Dictionary<string, EndPoint>();
        Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();

        Socket[] socConnection = new Socket[65535];
        private static int clientNum = 0;

        //private Thread myThread;
        Socket socketWatch = null;
        IPEndPoint localEP = null;
        EndPoint remote = null;

        public udpServer()
        {
            InitializeComponent();
        }

        private void udpServer_Load(object sender, EventArgs e)
        {
            if (this.DesignMode == false)
            {
                txtIP.SelectedIndex = 0;
                IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());
                foreach (IPAddress ip in ipHostEntry.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {//筛选IPV4
                        txtIP.Items.Add(ip.ToString());
                    }
                }
            }
        }


        private void btnListen_Click(object sender, EventArgs e)
        {
            try
            {
                socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

                if (txtIP.SelectedIndex == 0)
                {
                    localEP = new IPEndPoint(IPAddress.Any, Convert.ToInt32(txtPort.Text.Trim()));
                }
                else
                {
                    localEP = new IPEndPoint(IPAddress.Parse(txtIP.Text), Convert.ToInt32(txtPort.Text.Trim()));
                }
                socketWatch.Bind(localEP);
                ShowMsg(Convert.ToString(localEP) + "服务器启动监听成功!" + "\r\n" + "等待客户端连接");

                if (socConnection[0] == null)
                {
                    Thread thread = new Thread(new ParameterizedThreadStart(StartListener));
                    thread.IsBackground = true;
                    thread.Start(socConnection[clientNum]);
                    dictThread.Add(socConnection[clientNum].RemoteEndPoint.ToString(), thread);  //  将新建的线程 添加 到线程的集合中去。  
                }

            }
            catch (Exception ex)
            { }
         
           
        }

        private void StartListener(object sokConnectionparn)
        {

            while (true)
            {
                try
                {
                    string returnData = "";
                    byte[] bytes = new byte[1024];
                    IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

                    remote = (EndPoint)(sender);
                    int recv = socketWatch.ReceiveFrom(bytes, ref remote);
                    returnData = Encoding.UTF8.GetString(bytes);
                    this.Invoke((EventHandler)delegate
                    {
                        showinfo.AppendText(remote.ToString() + "-->" + returnData.Trim());
                        showinfo.Text += System.Environment.NewLine;
                        if (!dict.ContainsValue(remote))
                        {
                            byte[] sendBytes = Encoding.UTF8.GetBytes(remote.ToString() + "加入链接");
                            socketWatch.SendTo(sendBytes, remote);
                            dict.Add(remote.ToString().Trim(), remote);
                            ShowMsg(remote.ToString() + "加入链接");
                            lbOnline.Items.Add(remote.ToString());
                            clientNum++;
                            Thread thread = new Thread(new ParameterizedThreadStart(StartListener));
                            thread.IsBackground = true;
                            thread.Start(socConnection[clientNum]);

                            dictThread.Add(remote.ToString(), thread);  //  将新建的线程 添加 到线程的集合中去。  
                        }
                    });
                }
                catch
                {
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (this.DesignMode == false)
            {
                txtIP.SelectedIndex = 0;
                IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());
                foreach (IPAddress ip in ipHostEntry.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {//筛选IPV4
                        txtIP.Items.Add(ip.ToString());
                    }
                }
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //if (myThread != null)
            //{
            //    myThread.Abort();                
            //}
        }

        private void lbOnline_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                txtCl.Text = lbOnline.SelectedItem.ToString().Trim();
            }
            catch (Exception ex)
            { }
        }

        private void txtInfo_TextChanged(object sender, EventArgs e)
        {
            //选择richtextbox中内容的最后一个字节            
            this.txtInfo.Select(this.txtInfo.Text.Length, 1);
            //设置滚动到当前位置
            this.txtInfo.ScrollToCaret();
        }

        private void showinfo_TextChanged(object sender, EventArgs e)
        {
            //选择richtextbox中内容的最后一个字节            
            this.showinfo.Select(this.showinfo.Text.Length, 1);
            //设置滚动到当前位置
            this.showinfo.ScrollToCaret();
        }

        private void btnSendToAll_Click(object sender, EventArgs e)
        {
            string strKey = "";
            strKey = txtCl.Text.Trim();
            byte[] sendBytes = Encoding.UTF8.GetBytes(socketWatch.LocalEndPoint.ToString() + "-->" + txtMsgSend.Text.Trim());

            foreach (EndPoint s in dict.Values)
            {
                socketWatch.SendTo(sendBytes, s);
            }
            //txtMsgSend.Clear();
        }

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            
                 
        }
        void ShowMsg(string str)
        {
            this.Invoke((EventHandler)delegate
            {
                txtInfo.AppendText(str + "\r\n");
            });
        }
        private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcpListen fi = new tcpListen();
            fi.Show();
        }

        private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcpClient fi = new tcpClient();
            fi.Show();
        }

        private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            udpServer fi = new udpServer();
            fi.Show();
        }

        private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
        {
            udpClient fi = new udpClient();
            fi.Show();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            string strKey = "";
            strKey = txtCl.Text.Trim();
            byte[] sendBytes = Encoding.UTF8.GetBytes(socketWatch.LocalEndPoint.ToString() + "-->" + txtMsgSend.Text.Trim());
            if (string.IsNullOrEmpty(strKey) || strKey == "客户端")   // 判断是不是选择了发送的对象;  
            {
                MessageBox.Show("请选择你要发送的客户端!!!");
            }
            else
            {
                socketWatch.SendTo(sendBytes, dict[strKey]);
                showinfo.AppendText(socketWatch.LocalEndPoint.ToString() + "-->" + txtMsgSend.Text.Trim() + "\r\n");
                //txtMsgSend.Clear();
            }
        }
    }
}

UDP客户端代码

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;
using System.IO; 

namespace listen
{
    public partial class udpClient : Form
    {
        public Socket newclient = null;
        public bool Connected;
        public Thread myThread = null;
        public delegate void MyInvoke(string str);
        IPEndPoint ie = null;

        public udpClient()
        {
            InitializeComponent();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {

                string ip = txtServerIP.Text.Trim();
                int port = Convert.ToInt32(txtServerPort.Text.Trim());
                ie = new IPEndPoint(IPAddress.Parse(ip), port);
                newclient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            }
            catch (SocketException ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

        public void ReceiveMsg()
        {
            //byte[] arrMsgRec = new byte[1024];

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint remote = (EndPoint)(sender);
            //int recv = newclient.ReceiveFrom(arrMsgRec,ref remote);
            //string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, recv);// 将接受到的字节数据转化成字符串;
            //showMsg(strMsg);

            while (true)
            {
                //定义一个2M的缓存区;  
                byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                //将接受到的数据存入到输入  arrMsgRec中;  
                int length = -1;

                try
                {
                    length = newclient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;  
                }
                catch (SocketException se)
                {
                    //showMsg("异常1;" + se.Message);
                    return;
                }
                catch (Exception e)
                {
                    //showMsg("异常2:" + e.Message);
                    return;
                }
                if (arrMsgRec[0] != 1) // 表示接收到的是消息数据;  arrMsgRec[0] == 0)
                {
                    string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, length);// 将接受到的字节数据转化成字符串;  
                    showMsg(strMsg);
                }

                if (arrMsgRec[0] == 1) // 表示接收到的是文件数据;  
                {

                    try
                    {
                        SaveFileDialog sfd = new SaveFileDialog();
                        this.Invoke((EventHandler)delegate
                        {
                            if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                            {// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】  

                                string fileSavePath = sfd.FileName;// 获得文件保存的路径;  
                                // 创建文件流,然后根据路径创建文件;  
                                using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
                                {
                                    fs.Write(arrMsgRec, 0, length);
                                    showMsg("文件保存成功:" + fileSavePath);
                                }
                            }

                        });



                    }
                    catch (Exception aaa)
                    {
                        MessageBox.Show(aaa.Message);
                        if (myThread != null)
                        {
                            myThread.Abort();
                        }
                        break;
                    }
                }

            }
        }

        public void showMsg(string msg)
        {
            {
                try
                {
                    //在线程里以安全方式调用控件
                    if (txtReceiveMsg.InvokeRequired)
                    {
                        MyInvoke _myinvoke = new MyInvoke(showMsg);
                        txtReceiveMsg.Invoke(_myinvoke, new object[] { msg });
                    }
                    else
                    {
                        txtReceiveMsg.AppendText(msg + "\r\n");
                    }


                }
                catch (Exception ex)
                { }

            }
        }
        //ThreadStart myThreaddelegate = new ThreadStart(ReceiveMsg);

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                if (newclient != null)
                {
                    int m_length = txtSend.Text.Length;
                    byte[] data = new byte[m_length];
                    data = Encoding.UTF8.GetBytes(txtSend.Text.Trim());
                    newclient.SendTo(data, ie);
                    showMsg("我说:" + txtSend.Text);
                    //txtSend.Text = "";
                    if (myThread == null)
                    {
                        myThread = new Thread(ReceiveMsg);
                        myThread.IsBackground = true;
                        myThread.Start();
                    }
                }

            }
            catch (Exception ex)
            { }
        }

        private void udpClient_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (myThread != null)
            {
                myThread.Abort();
            }
        }

        private void txtReceiveMsg_TextChanged(object sender, EventArgs e)
        {
            //选择richtextbox中内容的最后一个字节            
            this.txtReceiveMsg.Select(this.txtReceiveMsg.Text.Length, 1);
            //设置滚动到当前位置
            this.txtReceiveMsg.ScrollToCaret();
        }

        private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcpListen fi = new tcpListen();
            fi.Show();
        }

        private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tcpClient fi = new tcpClient();
            fi.Show();
        }

        private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            udpServer fi = new udpServer();
            fi.Show();
        }

        private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
        {
            udpClient fi = new udpClient();
            fi.Show();
        }
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值