代码改变世界

SOCKET通讯

2012-08-15 18:08  C#与.NET探索者  阅读(228)  评论(0编辑  收藏  举报

(一)
服务端
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.Sockets;
using System.Net;
using System.Threading;
using System.IO;

using System.Runtime.Serialization.Formatters.Binary;
namespace Server
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        //保存每一个客户端对应的负责通信的socket
        Dictionary<string, Socket> dicConn = new Dictionary<string, Socket>();

        Socket socket;
        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;

            //创建一个负责监听的socket
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //ip地址
            IPAddress ip = IPAddress.Parse(txtServer.Text);
            //ip地址 + 端口号
            IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPort.Text));
            try
            {
                //绑定ip地址+端口号
                socket.Bind(point);
            }
            catch (Exception ex)
            {
                ShowMsg(ex.Message);
                return;
            }
          
            //设置监听队列的大小
            socket.Listen(10);

            ShowMsg("开始监听");

            Thread th = new Thread(Listen);
            //后台线程
            th.IsBackground = true;
            th.Start();
        }
      
        void Listen()
        {
            //不停监听客户端
            while (true)
            {
                Socket connect = null;
                try
                {
                    //负责通信的socket
                    //Accept会阻塞线程
                    connect = socket.Accept();

                    cboUsers.Items.Add(connect.RemoteEndPoint.ToString());
                    //
                    dicConn.Add(connect.RemoteEndPoint.ToString(), connect);
                    ShowMsg("\r\n" + connect.RemoteEndPoint.ToString() + "连接!!");
                }
                catch (Exception ex)
                {
                    ShowMsg("\r\n" + ex.Message);
                    return;
                }
              
                //不停的接收客户端发来的消息
                Thread th = new Thread(RecMsg);
                th.IsBackground = true;
                th.Start(connect);
            }
        }

        void RecMsg(object o)
        {
            Socket connect = o as Socket;

            //不停的接收客户端发来的消息
            while (true)
            {
                try
                {
                    //接收消息
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    //length实际接收的字节数
                    int length = connect.Receive(buffer);
                    string msg = System.Text.Encoding.GetEncoding("gbk").GetString(buffer, 0, length);
                    ShowMsg("\r\n" + connect.RemoteEndPoint.ToString() + ":" + msg);
                }
                catch (Exception ex)
                {
                    ShowMsg("\r\n" + ex.Message);
                    break;
                }
            }
         
        }
        //显示消息
        void ShowMsg(string msg)
        {
            txtLog.Text += msg;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        //服务器给客户端发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                //文字的字节数组
                byte[] buffer = System.Text.Encoding.GetEncoding("gbk").GetBytes(txtMsg.Text);
                //List<byte> list = new List<byte>();
                //list.Add(0); //第一个字节  标示是文字
                //list.AddRange(buffer);

                //创建要发送的对象
                Common.MyClass my = new Common.MyClass();
                my.Type = 0;//第一个字节  标示是文字
                my.Buffer = buffer;

                //序列化对象,返回字节数组

                string endpoint = cboUsers.Text;
                //获取客户端对应的socket
                dicConn[endpoint].Send(Serialize(my));
            }
            catch (Exception ex)
            {
                ShowMsg(ex.Message + "\r\n");
            }
          
        }
        //选择文件
        private void btnSelect_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtPath.Text = ofd.FileName;
            }
        }
        //发送文件
        private void btnSendFile_Click(object sender, EventArgs e)
        {
            using (FileStream fs = new FileStream(txtPath.Text, FileMode.Open))
            {
                byte[] buffer = new byte[1024*1024*5];
                int length = fs.Read(buffer, 0, buffer.Length);


                ////".jpg"  10字节  第一个字节 0/1  后9个字节保存文件的类型
                //List<byte> list = new List<byte>();
                //list.Add(1); //第一个字节  1 标示是文件
                //list.AddRange(buffer);

                List<byte> list = new List<byte>();
                for (int i = 0; i < length; i++)
                {
                    list.Add(buffer[i]);
                }

                Common.MyClass my = new Common.MyClass();
                my.Type = 1;
                my.Buffer = list.ToArray();

                try
                {
                    //发送
                    string endpoint = cboUsers.Text;
                    //获取客户端对应的socket
                    dicConn[endpoint].Send(Serialize(my));
                }
                catch (Exception ex)
                {
                    ShowMsg(ex.Message + "\r\n");
                }
              
            }
        }
        //发送震动
        private void btnZD_Click(object sender, EventArgs e)
        {
            byte[] buffer = new byte[1]; //标志位  2震动
            buffer[0] = 2;
            try
            {
                //发送
                string endpoint = cboUsers.Text;
                //获取客户端对应的socket
                dicConn[endpoint].Send(buffer);
            }
            catch (Exception ex)
            {
                ShowMsg(ex.Message + "\r\n");
            }
        }

        byte[] Serialize(Common.MyClass my)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                //把对象序列化到内存流
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(stream, my);

                //设置流的起始位置
                stream.Position = 0;

                //把流转换成字节数组
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);

                return buffer;
            }
        }
    }
}


(二)
客户端
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.Runtime.Serialization.Formatters.Binary;
namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        Socket client;
        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;

            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPAddress ip = IPAddress.Parse(txtServer.Text);

            IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPort.Text));
            try
            {   //连接服务器
                client.Connect(point);

                ShowMsg("连接成功");

                this.Text += " " + client.LocalEndPoint.ToString();
 
                //接收消息
                Thread th = new Thread(RecMsg);
                th.IsBackground = true;
                th.Start();
            }
            catch (Exception ex)
            {
                ShowMsg(ex.Message);
            }
        
        }
        //接收服务器发送过来的消息
        void RecMsg()
        {
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    //length实际接收的字节个数
                    int length = client.Receive(buffer);

                    ////没有数据直接返回
                    //if (buffer.Length <= 0)
                    //{
                    //    continue;
                    //}

                    //int type = buffer[0];// 读取标示位


                    Common.MyClass my = DeSerialize(buffer, length);
                    if (my == null)
                    {
                        continue;
                    }

                    //接收的是文字消息
                    if (my.Type == 0)
                    {
                        string msg = System.Text.Encoding.GetEncoding("gbk").GetString(my.Buffer,0,my.Buffer.Length);
                        ShowMsg(client.RemoteEndPoint + ":" + msg);
                    }
                    ////接收的是文件
                    else if (my.Type == 1)
                    {
                        //提示是否接收文件
                        if (MessageBox.Show("是否接收文件", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.OK)
                        {
                            //选择文件保存的位置
                            SaveFileDialog sfd = new SaveFileDialog();
                            if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                            {
                                //要保存的文件的路径
                                string path = sfd.FileName;

                                using (FileStream fs = new FileStream(path, FileMode.Create))
                                {
                                    //保存文件
                                    fs.Write(my.Buffer, 0, my.Buffer.Length);
                                }
                            }
                        }
                    }
                    //窗口震动
                    else if (my.Type == 2)
                    {
                        this.TopMost = true;
                        ZD();
                    }
                 
                }
                catch (Exception ex)
                {
                    ShowMsg(ex.Message);
                    break;
                }
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] buffer = System.Text.Encoding.GetEncoding("gbk").GetBytes(txtMsg.Text);
                client.Send(buffer);
            }
            catch (Exception ex)
            {
                ShowMsg(ex.Message);
            }
        }
        //显示消息
        void ShowMsg(string msg)
        {
            txtLog.Text += msg + "\r\n";
        }

        //窗口震动
        void ZD()
        {
            for (int i = 0; i < 10; i++)
            {
                Test();
                System.Threading.Thread.Sleep(50);
            }
        }

        string dir = "top";
        void Test()
        {
            if (dir == "top")
            {
                this.Location = new Point(this.Location.X + 10, this.Location.Y - 10);
                dir = "bottom";
            }
            else
            {
                dir = "top";
                this.Location = new Point(this.Location.X - 10, this.Location.Y + 10);
            }
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="buffer">反序列化的内容</param>
        /// <param name="length">有效的字节个数</param>
        /// <returns></returns>
        Common.MyClass DeSerialize(byte[] buffer, int length)
        {
            BinaryFormatter bf = new BinaryFormatter();
           
            //把字节数组的内容读到内存流中
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(buffer, 0, length);

                //设置流的起始位置
                ms.Position = 0;

                Common.MyClass my = bf.Deserialize(ms) as Common.MyClass;
                return my;
            }
        }
    }
}