关闭

C#学习笔记之Socket

175人阅读 评论(0) 收藏 举报
分类:

1、客户端:

窗口:

代码:

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;

namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // 声明一个负责通信的Socket。
        Socket socketSend = null;

        // 连接服务器
        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                // 实例化负责通信的Sokcet(协议族:IPv4, 套接字类型:流传递, 协议类型:TCP)
                socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Parse("127.0.0.1"); // 服务器地址
                IPEndPoint point = new IPEndPoint(ip, 8888);

                // 连接服务器
                socketSend.Connect(point);

                txtLog.AppendText("连接成功!\r\n");

                // 创建一个线程用来循环接收数据。
                Thread th = new Thread(Receive);
                th.IsBackground = true; // 设为后台线程
                th.Start(socketSend);   // 将通信用Socket传入线程。
            }
            catch
            { }
        }

        // 循环接收服务器发送的数据
        public void Receive(object socket)
        {
            Socket socketSend = (Socket)socket;

            try
            {
                while (true)
                {
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    int len = socketSend.Receive(buffer);   // 传输的数据都是字节数组类型的
                    string str = Encoding.Default.GetString(buffer, 0, len);
                    txtLog.AppendText("服务器说:" + str + "\r\n");
                }
            }
            catch { }
        }

        // 发送信息
        private void button1_Click(object sender, EventArgs e)
        {
            // 将要发送的数据转换成字节数组
            byte[] buffer = Encoding.Default.GetBytes(txtMsg.Text);

            // 给要传输的数据加一个标志位:
            // 如果传输的是文本信息,在数据的前面加一个“0”。
            List<byte> list = new List<byte>();
            list.Add(0);
            list.AddRange(buffer);
            byte[] newBuffer = list.ToArray(); // 新的字节数组是加了标志位之后的数据。

            socketSend.Send(newBuffer); // 发送数据
        }

        // 取消线程间访问的限制
        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        // 发送文件
        private void button2_Click(object sender, EventArgs e)
        {
            // 打开文件对话框
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "请选择文件:";
            ofd.ShowHelp = true;
            ofd.InitialDirectory = @"D:\";
            ofd.Filter = "文本文件(*.txt)|*.txt";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string path = ofd.FileName; // 获取要发送文件的路径
                txtFile.Text = path;
                
                using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read))
                {
                    // 将文件中的数据读取到字节数组(buffer)中。
                    byte[] buffer = new byte[fsRead.Length];
                    int len = fsRead.Read(buffer, 0, buffer.Length);

                    // 声明一个list集合,存储要发送的字节数组和标志位
                    List<byte> list = new List<byte>();
                    list.Add(1); // 如果发送的是文件数据,加标志位“1”。   
                    list.AddRange(buffer);
                    // 将添加了标志位的集合重新转换成字节数组
                    byte[] newBuffer = list.ToArray();

                    // 发送文件数据
                    socketSend.Send(newBuffer, 0, len+1, SocketFlags.None);
                }
            }
        }
    }
}


2、服务器端

窗口:


代码:

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;

namespace Server
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Socket socketListen = null; // 声明一个用于监听的Socket
        Socket socketSend = null;   // 声明一个用于通信的Socket

        // 声明一个集合存储客户端地址,可以实现多个客户端。
        Dictionary<string, Socket> dic = new Dictionary<string, Socket>();

        // 开启服务器
        private void btnOpenServer_Click(object sender, EventArgs e)
        {
            try
            {
                // 实例化监听套接字(IPv4, 流传递, TCP协议)
                socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //IPAddress ip = IPAddress.Parse("127.0.0.1");    // 服务器端IP地址
                IPAddress ip = IPAddress.Any;
                IPEndPoint point = new IPEndPoint(ip, 8888);

                // 绑定服务器端IP地址和端口
                socketListen.Bind(point);

                // 监听,同一时间点最多允许10个客户端连接
                socketListen.Listen(10);

                txtLog.AppendText("服务器打开成功,等待客户端连接!\r\n");

                // 创建一个线程用于循环监听客户端的连接
                Thread th = new Thread(Listen);
                th.IsBackground = true; // 设为后台线程
                th.Start(socketListen);
            }
            catch { }
        }

        // 循环等待客户端连接
        public void Listen(object sock)
        {
            try
            {
                while (true)
                {
                    Socket socket = (Socket)sock;

                    // 等待客户端连接,连接成功返回一个负责和客户端通信的Socket
                    socketSend = socket.Accept();

                    // 将客户端地址和端口号,以及和客户端通信的套接字加入集合中。
                    dic.Add(socketSend.RemoteEndPoint.ToString(), socketSend);

                    // 获取客户端IP地址和端口号,显示在ComboBox控件上
                    cboAddr.Items.Add(socketSend.RemoteEndPoint.ToString());
                    txtLog.AppendText(socketSend.RemoteEndPoint.ToString() + ":连接成功!\r\n");

                    // 创建一个线程,用于循环接收客户端发来的信息。
                    Thread th = new Thread(Receive);
                    th.IsBackground = true;
                    th.Start(socketSend);
                }
            }
            catch { }
        }

        // 循环接收信息
        public void Receive(object socket)
        {
            try
            {
                Socket socketSend = (Socket)socket;
                while (true)
                {
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    int len = socketSend.Receive(buffer);

                    if (buffer[0] == 0) // 如果标志位是“0”,表示接收到的是文本信息。
                    {
                        // 实际数据是从buffer的第二位开始,长度是接收到的数据长度减一。
                        string str = Encoding.Default.GetString(buffer, 1, len - 1);
                        txtLog.AppendText(socketSend.RemoteEndPoint.ToString() + "说:" + str + "\r\n");
                    }
                    else if (buffer[0] == 1) // 如果标志位是“1”,接收的是文件。
                    {
                        // 保存接收的文件。
                        SaveFileDialog sfd = new SaveFileDialog();
                        sfd.Title = "请选择保存目录";
                        sfd.ShowHelp = true;
                        sfd.InitialDirectory = @"D:\";
                        sfd.Filter = "文本文件|*.txt|所有文件|*.*";

                        // 有的系统要加“this”才会显示对话框,有的不用
                        //if (sfd.ShowDialog() == DialogResult.OK)
                        if (sfd.ShowDialog(this) == DialogResult.OK)
                        {
                            string path = sfd.FileName;
                            using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
                            {
                                fsWrite.Write(buffer, 1, len - 1);
                            }
                        }
                        MessageBox.Show("保存成功!");
                    }
                }
            }
            catch { }
        }

        // 取消线程间访问限制
        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        // 发送信息
        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                dic[cboAddr.Text].Send(Encoding.Default.GetBytes(txtMsg.Text));
            }
            catch { }
        }
    }
}



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20568次
    • 积分:1351
    • 等级:
    • 排名:千里之外
    • 原创:118篇
    • 转载:4篇
    • 译文:0篇
    • 评论:0条