吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1357|回复: 1
收起左侧

[其他原创] 【原创】C# Socket网络通信 基础代码 请求品鉴

[复制链接]
一蓑烟雨任余年 发表于 2020-3-12 15:15
话不多说 直接上图
服务端:

image.png
客户端:
image.png
客户端服务端执行文件(exe) 客户端 服务端 可执行文件.zip (11.74 KB, 下载次数: 16)
服务端关键代码
[C#] 纯文本查看 复制代码
using System;using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
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 MyFunc;
namespace _10_13_Socket网络通信
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //获取本机ip
            
            txtIp.Text = "192.168.1.53";
            txtPoint.Text = "50000";
            //忽略线程检查
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        Thread th;
        IPEndPoint point;
        private void BtnListen_Click(object sender, EventArgs e)
        {
            try
            {
                //创建侦听socket 采用Tcp stream流 IPV4协议
                Socket sktListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //获取ip和端口号
                
                point = new IPEndPoint(IPAddress.Parse(txtIp.Text), Convert.ToInt32(txtPoint.Text));
                sktListen.Bind(point);//绑定通信信息(ip 和端口号)
                sktListen.Listen(10);//设置访问队列
                                     //由于侦听函数Accept()是一直在循环 如果用主进程调用此函数 程序会卡死 因此要创建新线程
                th = new Thread(Listen);
                th.IsBackground = true;
                th.Start(sktListen);
                Control.CheckForIllegalCrossThreadCalls = false;
            }
            catch
            {


            }

        }
        public void Listen(object o)
        {
            try
            {
                Socket newsktListen = o as Socket;//监听
                Socket socketLink;//监听数据
                newsktListen.Listen(10);
                while (true)//用死循环来无限等待客户端连接
                {

                    socketLink = newsktListen.Accept();//无限循环 直到接收到为止
                                                       //Accept结束 必定有客户端进入 这时就要给下拉框以及集合里添加数据了
                    GetReomtePoint(socketLink.RemoteEndPoint, socketLink);
                    txtMsg.AppendText(socketLink.RemoteEndPoint.ToString() + "链接成功\r\n");
                    Thread thMsg = new Thread(GetByte);
                    thMsg.Start(socketLink);

                }

            }
            catch (Exception)
            {

                throw;
            }





        }
        //客户连接成功之后 再创建一个线程来不断接收通讯信息
        public void GetByte(Object socketLink)
        {
            try
            {
                Socket newsocketLink = socketLink as Socket;
                //这个时候已经有客户端连接上了 写一个方法用来给下拉框赋值

                string str = "";
                while (true)
                {
                    byte[] buffer = new byte[1024];
                    int r = newsocketLink.Receive(buffer);
                    str = newsocketLink.RemoteEndPoint.ToString() + "Say:" + System.Text.Encoding.Default.GetString(buffer, 0, r);
                    if (r == 0)
                    {
                        break;
                    }
                    txtMsg.AppendText(str + "\r\n");
                }
            }
            catch (Exception)
            {

                throw;
            }



        }
        Dictionary<string, Socket> infodic = new Dictionary<string, Socket>();
        int i = 0;
        /// <summary>
        /// 这个方法是给下拉框赋值 因为后期也要选择客户信息 跟选定的IP通信 因此要用集合记录下来ip 和跟ip通信的socket
        /// </summary>
        /// <param name="point"></param>
        /// <param name="newsocketLink"></param>
        public void GetReomtePoint(EndPoint point, Socket newsocketLink)
        {


            infodic.Add(point.ToString(), newsocketLink);
            cmbIPEndPoint.Items.Add(point);

            cmbIPEndPoint.SelectedIndex = i;
            i++;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {


        }

        private void BtnSend_Click(object sender, EventArgs e)
        {
            try
            {
                //插入0表示发送文本
                
                //发送txtsendmsg中的txt 并给字节数组的第一个索引插入0 
                byte []bytedata = System.Text.Encoding.Default.GetBytes(txtSendMsg.Text);
                bytedata = MyFunc.ByteOperate.Insert(bytedata, 0, 0);
                Send(bytedata,txtSendMsg.Text);

            }
            catch (Exception)
            {

                throw;
            }
            //根据key寻找value

        }
        //写一个发送的方法
        public void Send(byte []buffer,string txt)
        {
            Socket newsocketLink = infodic[cmbIPEndPoint.SelectedItem.ToString()];

            newsocketLink.Send(buffer);
            
            txtMsg.AppendText("Say:" + txt + "\r\n");
            //点击之后txtbox中的文本要清空
            txtSendMsg.Text = "";
        }
        OpenFileDialog ofd;
        private void BtnSendFile_Click(object sender, EventArgs e)
        {
            ofd = new OpenFileDialog();
            ofd.InitialDirectory = @"F:\PKX桌面";
            ofd.Title = "请选择要发送的文件";
            ofd.Filter = "图片文件|*.jpg|文本文件|*.txt|音乐文件|*.wav|视频文件|*.rmvb|所有文件|*.*";
            ofd.ShowDialog();
            string path = ofd.FileName;
            if (path=="")
            {
                return;
            }
            else
            {
                using (FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    byte[] buffer = new byte[fsRead.Length];
                    fsRead.Read(buffer, 0, buffer.Length);
                    buffer = MyFunc.ByteOperate.Insert(buffer, 1, 0);//插入1 表示发送文件
                                                                     //发送文件
                    Send(buffer, "发送文件:" + path);
                }
            }
            
            
        }

        private void BtnShake_Click(object sender, EventArgs e)
        {
            byte[] buffer = new byte[1];
            buffer = MyFunc.ByteOperate.Insert(buffer, 2, 0);//字节用2表示
            Send(buffer,"给对方发送震动");
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Process.GetCurrentProcess().Kill();
        }
    }
}

客户端关键代码:
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
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 MyFunc;
namespace _10_14_Socket网络通信_客户端
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Socket socClient;
        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);



        }

        private void BtnSend_Click(object sender, EventArgs e)
        {
            try
            {
                socClient.Send(System.Text.Encoding.Default.GetBytes(txtSend.Text));
                txtMsg.AppendText("Say:" + txtSend.Text + "\r\n");
                txtSend.Text = "";
            }
            catch (Exception)
            {

                throw;
            }


        }
        public void GetByte()
        {
            try
            {
                IPAddress ip = IPAddress.Parse("192.168.1.53"); //new IPAddress(System.Text.Encoding.Default.GetBytes("192.168.1.53"));
                socClient.Connect(ip,50000);
                button1.Hide();
                string str = "";
                
                while (true)//这里一定要死循环 循环接收 不能用socClient.Available != 0
                {

                    byte[] buffer = new byte[1024 * 1024 * 2];
                    int r = socClient.Receive(buffer);
                    //判断收到的字节的第一个下标的值
                    switch (buffer[0])
                    {
                        case 0://是文本
                            {
                                buffer = MyFunc.ByteOperate.Remove(buffer, 0);
                                str = socClient.RemoteEndPoint.ToString() + "Say:" + System.Text.Encoding.Default.GetString(buffer, 0, r);
                                if (r == 0)
                                {
                                    break;
                                }
                                txtMsg.AppendText(str + "\r\n");
                            }
                            break;
                        case 1://是文件
                            {
                                
                                buffer = MyFunc.ByteOperate.Remove(buffer, 0);//移除协议
                                                                              //接收到文件 需要打开保存窗口
                                SaveFileDialog sfd = new SaveFileDialog();
                                sfd.Title = "请选择要保存的文件路径和文件名称";
                                sfd.InitialDirectory = @"F:\PKX桌面";
                                sfd.ShowDialog(this);
                                if (sfd.FileName == "")
                                {
                                    return;
                                }
                                else
                                {
                                    using (FileStream fsWrite = new FileStream(sfd.FileName, FileMode.OpenOrCreate, FileAccess.Write))
                                    {
                                        fsWrite.Write(buffer, 0, buffer.Length);
                                    }
                                    MessageBox.Show("保存成功!");
                                }
                            }
                            break;
                        case 2://发送的是震动
                            {
                                this.Show();
                                for (int i = 0; i < 500; i++)
                                {
                                    //this.Location = new Point(220,300);
                                    //this.Location = new Point(230, 310);
                                    //this.Location.X = this.Location.X + 50;
                                    this.Location = new Point(this.Location.X + 10, this.Location.Y + 10);
                                    this.Location = new Point(this.Location.X - 10, this.Location.Y - 10);
                                }
                               

                            }
                            break;
                        default:
                            break;
                    }




                }
            }
            catch (Exception)
            {

                throw;
            }

        }

        private void Button1_Click(object sender, EventArgs e)
        {


            Thread th = new Thread(GetByte);
            th.IsBackground = true;
            th.Start();
            Control.CheckForIllegalCrossThreadCalls = false;

        }

        private void BtnShake_Click(object sender, EventArgs e)
        {

        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Process.GetCurrentProcess().Kill();
        }
    }
}




发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 一蓑烟雨任余年 发表于 2020-3-12 15:44
对了 命名空间里using MyFunc 主要是引用了我自己写的字节操作的函数
因为如果客户发送图片 文字 或者震动的时候 接收方无法判断 需要在发送前插入一个字节 让接收方来判断接收到的是什么
具体实现代码如下:
[C#] 纯文本查看 复制代码
 public static class ByteOperate
    {
        /// <summary>
        /// 给自己数组插入指定的字节
        /// </summary>
        /// <param name="oldbyte">原字节数组</param>
        /// <param name="insertbyet">要插入的字节</param>
        /// <param name="index">要插入的索引</param>
        /// <returns></returns>
        public static byte[] Insert(byte []oldbyte,byte insertbyet,int index)
        {
            List<byte> list = new List<byte>();
            list = oldbyte.ToList();
            list.Insert(index, insertbyet);
            return list.ToArray();
        }
        /// <summary>
        /// 移除数组中的某个下标的元素
        /// </summary>
        /// <param name="oldbyte">元素组</param>
        /// <param name="index">要移除的某个下标</param>
        /// <returns>移除某个元素后的数组</returns>
        public static byte[] Remove(byte[] oldbyte, int index)
        {
            List<byte> list = new List<byte>();
            list = oldbyte.ToList();
            list.RemoveAt(index);
            return list.ToArray();
        }
    }
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 02:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表