C#socket通信

服务端

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

namespace 我的聊天程序
{
    public partial class serverForm : Form
    {
        public serverForm()
        {
            InitializeComponent();
        }
        
        Socket acceptUser;//连接客户端的socket实例
        Dictionary<string,Socket> userList = new Dictionary<string, Socket>();
        bool[] messType = { true, false, false };//默认用户要发送文字消息 [0]:发文字消息 [1]:发文件 [2]:发抖动窗口消息
        string sendFilePath;
        string fileName;
        /// <summary>
        /// 开始监听
        /// 1.创建socket对象
        /// 2.绑定IP和端口
        /// 3.设置监听队列
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void startListen_Click(object sender, EventArgs e)
        {
           //1.创建socket对象
            //参数1: 寻址方案:IP 4版本
            //参数2: 数据传输方式 以流的方式传输
            //参数3: 数据传输协议 TCP协议
           Socket serveSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

            //2.绑定IP和端口
           try
           {
               IPAddress severIP = IPAddress.Parse(showIPAdd.Text.ToString());
               IPEndPoint ipAndPor = new IPEndPoint(severIP, Convert.ToInt32(showPort.Text));
               serveSocket.Bind(ipAndPor);

               //3.设置监听队列

               serveSocket.Listen(10);
               loadSever();

               //开辟一个线程去等待用户连接
               Thread waitUserAccpet = new Thread(listen);
               waitUserAccpet.IsBackground = true;
               waitUserAccpet.Start(serveSocket);

               sendFile.Enabled = true;
               accepUsertList.Enabled = true;
               sendShake.Enabled = true;
               serveMessEdit.Enabled = true;
               serveSendMess.Enabled = true;
               startListen.Enabled = false;
           }
           catch 
           {
               serveShowMessge("IP地址或端口无效,请确认无误后在重试");
           }
                    
        }

        /// <summary>
        /// 显示整个过程需要显示的文本
        /// </summary>
        /// <param name="showMess"></param>
        private void serveShowMessge(string showMess)
        {
            showSeverLog.AppendText(showMess+"\r\n");
        }

        /// <summary>
        /// 因为不能让主线程去一直等待用户连接
        /// 新建一个线程专门负责去等待用户连接
        /// </summary>
        /// <param name="serveSock"></param>
        private void listen(object o)
        {
            Socket serveSocketMes = o as Socket;
            while (true)
            {
                try
                {
                    acceptUser = serveSocketMes.Accept();
                    serveShowMessge(acceptUser.RemoteEndPoint.ToString() + ":\t" + "连接成功");
                    userList.Add(acceptUser.RemoteEndPoint.ToString(), acceptUser);
                    accepUsertList.Items.Add(acceptUser.RemoteEndPoint.ToString());
                    Thread recevieUseerMes = new Thread(recevie);
                    recevieUseerMes.IsBackground = true;
                    recevieUseerMes.Start();
                }
                catch
                {

                }
              
            }
        }
        /// <summary>
        /// 程序加载时显示字符
        /// </summary>
        private void loadSever()
        {
            serveShowMessge("服务已启动");
            Thread.Sleep(1000);
            serveShowMessge("正在开启监听");
            Thread.Sleep(1000);
            serveShowMessge("监听成功等待用户连接");
        }

        /// <summary>
        /// 取消对跨线程访问的限制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serverForm_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        /// <summary>
        /// 接收客户端发送的消息
        /// </summary>
        /// <param name="serverSocke"></param>
        private void recevie()
        {
            byte[] recevieMessBuf = new byte[1024 * 1024 * 5];
            while (true)
            {
                try
                {
                    int recevieCountBy = acceptUser.Receive(recevieMessBuf);

                    if (recevieCountBy == 0)
                    {
                        serveShowMessge("对方可能已经下线了");
                        break;
                    }
                    MessageHandle(recevieMessBuf, recevieCountBy);
                }
                catch { }
            }
          
        }

        /// <summary>
        /// 给客户端发消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serveSendMess_Click(object sender, EventArgs e)
        {
            SendMessHandle();
            messType[0] = true;
            messType[1] = false;
            messType[2] = false;
        }
        /// <summary>
        /// 发送消息处理
        /// </summary>
        private void SendMessHandle()
        {
            List<byte> messByte = new List<byte>();
            if (messType[0])
            {
                try
                {
                    messByte.Add(0);
                    messByte.AddRange(Encoding.Default.GetBytes(serveMessEdit.Text));
                    byte[] sendMessBuffer = messByte.ToArray();
                    userList[accepUsertList.SelectedItem.ToString()].Send(sendMessBuffer);
                    serveShowMessge("自己:" + serveMessEdit.Text);
                    serveMessEdit.Clear();
                }
                catch { }
               
            }
            else if (messType[1])
            {
                try
                {
                    //1.先发送文件名
                    messByte.Add(1);
                    messByte.AddRange(Encoding.Default.GetBytes(Path.GetFileName(sendFilePath)));

                    byte[] sendMessBuffer = messByte.ToArray();
                    userList[accepUsertList.SelectedItem.ToString()].Send(sendMessBuffer);
                    serveShowMessge("自己:" + Path.GetFileName(sendFilePath));

                    messByte.Clear();
                    //2.正式发送文件
                    messByte.Add(2);
                    using (FileStream readSendFile = new FileStream(sendFilePath, FileMode.Open, FileAccess.Read))
                    {
                        byte[] fileBuffer = new byte[1024 * 1024 * 4];
                        int readByCount = readSendFile.Read(fileBuffer, 0, fileBuffer.Length);
                        messByte.AddRange(fileBuffer);
                        messByte.RemoveRange(readByCount + 1, messByte.Count - readByCount - 1);
                        sendMessBuffer = messByte.ToArray();
                        userList[accepUsertList.SelectedItem.ToString()].Send(sendMessBuffer);
                    }
                }
                catch { }
               
            }
            else
            {
                try
                {
                    byte[] buffer = { 3 };
                    userList[accepUsertList.SelectedItem.ToString()].Send(buffer);
                    serveShowMessge("自己:\t给对方发了一个窗口抖动消息");
                }
                catch { }

            }
        }
        /// <summary>
        /// 用户需要发送文件
        /// 确定用户选择了文件后,传递用户选择的文件名
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sendFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog selectSendFile = new OpenFileDialog();
            selectSendFile.Title = "选择你要发送的文件";
            selectSendFile.Filter = "文本文件|*.txt|所有文件|*.*";
            selectSendFile.Multiselect = false;
            selectSendFile.ShowDialog();
            sendFilePath = selectSendFile.FileName;
            if (sendFilePath != "")
            {
                messType[0] = false;
                messType[1] = true;
                messType[2] = false;              
            }
        }
        /// <summary>
        /// 消息有很多类,所以根据缓冲字节数组的第一位鉴别是哪类消息
        /// [0]=0 代表接收的是文字消息
        /// [0]=1 代表接收的文件名消息
        /// [0]=2 代表接收到用文件的字节
        /// [0]=3 代表接收的时抖动窗口消息
        /// </summary>
        /// <param name="mesBuffer">接收其他用户发送的字节数组 </param>
        /// <param name="count">实际接收的字节个数</param>
        private void MessageHandle(byte[] mesBuffer,int count)
        {
            try
            {
                if (mesBuffer[0] == 0)
                {
                    string textMes = Encoding.Default.GetString(mesBuffer, 1, count - 1);
                    serveShowMessge(acceptUser.RemoteEndPoint.ToString() + ":\t" + textMes);
                }
                else if (mesBuffer[0] == 1)
                {
                    fileName = Encoding.Default.GetString(mesBuffer, 1, count - 1);
                    serveShowMessge(acceptUser.RemoteEndPoint.ToString() + ":\t" + fileName);
                }
                else if (mesBuffer[0] == 2)
                {
                    string fileFullPath = @"C:\Users\Administrator\Desktop\";
                    fileFullPath += fileName;
                    using (FileStream writeRecivevFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write))
                    {
                        writeRecivevFile.Write(mesBuffer, 1, count - 1);
                    }
                    serveShowMessge(fileName + "接收成功");
                    fileName = null;
                }
                else
                {
                    formShake();
                    serveShowMessge(acceptUser.RemoteEndPoint.ToString() + ":\t" + "给你发了一个窗口抖动");

                }
            }
            catch { }
           
        }
        /// <summary>
        /// 抖动窗口
        /// </summary>
        private void formShake()
        {
            for (int i = 0; i < 500; i++)
            {
                this.Location = new Point(25, 100);
                this.Location = new Point(30, 100);
            }  
        }
        /// <summary>
        /// 窗口抖动消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sendShake_Click(object sender, EventArgs e)
        {
            messType[0] = false;
            messType[1] = false;
            messType[2] = true;  
        }


    }
}
客户端

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.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace 客户端
{
    public partial class userForm : Form
    {
        public userForm()
        {
            InitializeComponent();
        }
        Socket userSocket;
        string sendFilePath;
        string fileName;
        bool[] messType = { true, false, false };//默认用户要发送文字消息 [0]:发文字消息 [1]:发文件 [2]:发抖动窗口消息
        /// <summary>
        /// 客户端连接服务器
        /// 1.创建一个socket对象
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void connectServe_Click(object sender, EventArgs e)
        {
            //1.创建一个socket对象
             userSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            
            //用域名绑定IP
             //IPHostEntry hostInfo = Dns.GetHostEntry("19u232j797.51mypc.cn");
             //IPAddress ipAddress = hostInfo.AddressList[0]; 

            //2.连接服务器
            IPAddress serverIP = IPAddress.Parse(showUserIP.Text);
             userSocket.Connect(serverIP, Convert.ToInt32(showUserPort.Text));
            showUserMessage("连接成功");
            
            //启动发送消息的控件
            sendFile.Enabled = true;
            sendShakeMes.Enabled = true;
            userMesEdit.Enabled = true;
            userSendMes.Enabled = true;

             //接受客户端发送的消息
            Thread recevieServeMes = new Thread(recevie);
            recevieServeMes.IsBackground = true;
            recevieServeMes.Start();

            connectServe.Enabled = false;

        }
    
        /// <summary>
        /// 在整个过程中需要显示在消息日志上的字符
        /// </summary>
        /// <param name="userMessage"></param>
        private void showUserMessage(string userMessage)
        {
            showUserLog.AppendText(userMessage+"\r\n");
        }
        /// <summary>
        /// 接收服务端发送的消息
        /// </summary>
        private void recevie()
        {
            while (true)
            {
                try
                {
                    byte[] receServMesBuf = new byte[1024 * 1024 * 5];
                    int recevieCountBy = userSocket.Receive(receServMesBuf);
                    MessageHandle(receServMesBuf, recevieCountBy);
                }
                catch { }

            }
        }
        /// <summary>
        /// 客户端给服务器发消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void userSendMes_Click(object sender, EventArgs e)
        {

            SendMessHandle();
            messType[0] = true;
            messType[1] = false;
            messType[2] = false;
        }

        /// <summary>
        /// 取消对跨线程的限制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void userForm_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        /// <summary>
        /// 发送文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sendFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog selectSendFile = new OpenFileDialog();
            selectSendFile.Title = "选择你要发送的文件";
            selectSendFile.Filter = "文本文件|*.txt|所有文件|*.*";
            selectSendFile.Multiselect = false;
            selectSendFile.ShowDialog();
            sendFilePath = selectSendFile.FileName;
            if (sendFilePath != "")
            {
                messType[0] = false;
                messType[1] = true;
                messType[2] = false;
            }
        }
        /// <summary>
        /// 发送消息处理
        /// </summary>
        private void SendMessHandle()
        {
            List<byte> messByte = new List<byte>();
            if (messType[0])
            {
                try
                {
                    messByte.Add(0);
                    messByte.AddRange(Encoding.Default.GetBytes(userMesEdit.Text));
                    byte[] sendMessBuffer = messByte.ToArray();
                    userSocket.Send(sendMessBuffer);
                    showUserMessage("自己:" + userMesEdit.Text);
                    userMesEdit.Clear();
                }
                catch { }
               
            }
            else if (messType[1])
            {
                try
                {
                    //1.先发送文件名
                    messByte.Add(1);
                    messByte.AddRange(Encoding.Default.GetBytes(Path.GetFileName(sendFilePath)));

                    byte[] sendMessBuffer = messByte.ToArray();
                    userSocket.Send(sendMessBuffer);
                    showUserMessage("自己:" + Path.GetFileName(sendFilePath));

                    messByte.Clear();
                    //2.正式发送文件
                    messByte.Add(2);
                    using (FileStream readSendFile = new FileStream(sendFilePath, FileMode.Open, FileAccess.Read))
                    {
                        byte[] fileBuffer = new byte[1024 * 1024 * 4];
                        int readByCount = readSendFile.Read(fileBuffer, 0, fileBuffer.Length);
                        messByte.AddRange(fileBuffer);
                        messByte.RemoveRange(readByCount + 1, messByte.Count - readByCount - 1);
                        sendMessBuffer = messByte.ToArray();
                        userSocket.Send(sendMessBuffer);
                    }
                }
                catch { }

            }
            else
            {
                try
                {
                    byte[] buffer = { 3 };
                    userSocket.Send(buffer);
                    showUserMessage("自己:\t给对方发了一个窗口抖动消息");
                }
                catch { }

            }
        }

        /// <summary>
        /// 消息有很多类,所以根据缓冲字节数组的第一位鉴别是哪类消息
        /// [0]=0 代表接收的是文字消息
        /// [0]=1 代表接收的文件名消息
        /// [0]=2 代表接收到用文件的字节
        /// [0]=3 代表接收的时抖动窗口消息
        /// </summary>
        /// <param name="mesBuffer">接收其他用户发送的字节数组 </param>
        /// <param name="count">实际接收的字节个数</param>
        private void MessageHandle(byte[] mesBuffer, int count)
        {
            try
            {
                if (mesBuffer[0] == 0)
                {
                    string textMes = Encoding.Default.GetString(mesBuffer, 1, count - 1);
                    showUserMessage(userSocket.RemoteEndPoint.ToString() + ":\t" + textMes);
                }
                else if (mesBuffer[0] == 1)
                {
                    fileName = Encoding.Default.GetString(mesBuffer, 1, count - 1);
                    showUserMessage(userSocket.RemoteEndPoint.ToString() + ":\t" + fileName);
                }
                else if (mesBuffer[0] == 2)
                {
                    string fileFullPath = @"C:\Users\Administrator\Desktop\";
                    fileFullPath += fileName;
                    using (FileStream writeRecivevFile = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write))
                    {
                        writeRecivevFile.Write(mesBuffer, 1, count - 1);
                    }
                    showUserMessage(fileName + "接收成功");
                    fileName = null;
                }
                else
                {
                    formShake();
                    showUserMessage(userSocket.RemoteEndPoint.ToString() + ":\t" + "给你发了一个窗口抖动");

                }
            }
            catch { }
         
        }

        /// <summary>
        /// 抖动窗口
        /// </summary>
        private void formShake()
        {
            for (int i = 0; i < 500; i++)
            {
                this.Location = new Point(25, 100);
                this.Location = new Point(30, 100);
            }
        }

        private void sendShakeMes_Click(object sender, EventArgs e)
        {
            messType[0] = false;
            messType[1] = false;
            messType[2] = true;
        }

    }
}
 

转载于:https://my.oschina.net/u/3026393/blog/1592674

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值