C C++最全C#实现异步Socket通信(控制台)_c# socket 异步accept,2024年最新C C++开发实战

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

            else if (conns[i].isUse == false)
            {
                return i;
            }

        }
        return -1;
    }
    public void Start(string host, int port)//初始化连接池,开始监听端口
    {
        conns = new Conn[maxConn];
        for (int i = 0; i < maxConn; i++)
        {
            conns[i] = new Conn();
        }
        listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPAddress ipAdr = IPAddress.Parse(host);
        IPEndPoint ipEp = new IPEndPoint(ipAdr, port);
        listenfd.Bind(ipEp);
        listenfd.Listen(maxConn);
        listenfd.BeginAccept(AcceptCb, null);
        Console.WriteLine("[服务器]启动成功");

    }
    private void AcceptCb(IAsyncResult ar)//回调函数,接收到客户端的连接
    {
        try
        {
            Socket socket = listenfd.EndAccept(ar);
            int index = NewIndex();
            if (index < 0)
            {
                socket.Close();
                Console.WriteLine("[警告]连接已满");
            }
            else
            {
                Conn conn = conns[index];
                conn.Init(socket);
                string adr = conn.GetAdress();
                Console.WriteLine("客户端连接[" + adr + "] conn池ID:" + index);
                conn.socket.BeginReceive(conn.readBuff, conn.buffCount, conn.BuffRemain(), SocketFlags.None, ReceiveCb, conn);//接收客户端发送的内容
                listenfd.BeginAccept(AcceptCb, null);//继续监听,等待客户端连接,
            }

        }
        catch (System.Exception ex)
        {
            Console.WriteLine("AcceptCb失败:" + ex.Message);
        }
    }
    private void ReceiveCb(IAsyncResult ar)//回调函数 接收到客户端内容进行调用
    {
        Conn conn = (Conn)ar.AsyncState;
        try
        {
            int count = conn.socket.EndReceive(ar);//获取客户端内容的字节数
            if (count <= 0)
            {
                Console.WriteLine("收到 【" + conn.m_name + "】断开连接 ");
                conn.close();
                return;
            }
            string str = System.Text.Encoding.Default.GetString(conn.readBuff, 0, count);
            //将客户端名字和消息内容分割开 yar:hello =》yar hello
            string[] arr = str.Split(':');
            string name = "";
            int t = 0;
            foreach (string s in arr)
            {
                if (t == 0) name = s ;
                t = 1;
                str = s;
            }
            conn.m_name = name;



            Console.WriteLine("收到 【" + conn.m_name + "】数据: " + str);
            byte[] bytes = System.Text.Encoding.Default.GetBytes(conn.m_name+":"+str);
            for (int i = 0; i < conns.Length; i++)//转播给其他正在使用的客户端
            {
                if (conns[i] == null)
                    continue;
                if (!conns[i].isUse)
                    continue;
                Console.WriteLine("将消息转播给" + conns[i].m_name);
                conns[i].socket.Send(bytes);
            }
            conn.socket.BeginReceive(conn.readBuff, conn.buffCount, conn.BuffRemain(), SocketFlags.None, ReceiveCb, conn);//继续接收该客户端的数据
        }
        catch (System.Exception ex)
        {
            Console.WriteLine("收到 【" + conn.m_name + "】断开连接 ");
            conn.close();
            return;
        }
    }
}
class Program
{

   
    static void Main(string[] args)
    {
        Serv serv = new Serv();
        serv.Start("127.0.0.1", 1234);
        while (true)
        {
            string str = Console.ReadLine();
            switch (str)
            {
                case "quit":
                    return;
            }
        }


    }


}

}


### 2 客户端


客户端示意图:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200306092041612.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNjcwMTU3,size_16,color_FFFFFF,t_70)



using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;

namespace Client
{
class Cli
{
string m_name = “无名”;
Socket socket;
const int BUFFER_SIZE = 1024;
public byte[] readBuff = new byte[BUFFER_SIZE];
public Cli(String name)
{
m_name = name;
}
public void Connection()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string host = “127.0.0.1”;
int port = 1234;
socket.Connect(host, port);
// socket.LocalEndPoint.ToString();
socket.BeginReceive(readBuff,0,BUFFER_SIZE,SocketFlags.None,ReceiveCb,null);
}
private void ReceiveCb(IAsyncResult ar)
{
try
{
int count = socket.EndReceive(ar);
string str = System.Text.Encoding.Default.GetString(readBuff, 0, count);
Console.WriteLine(str);
socket.BeginReceive(readBuff, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null);

        }
        catch (System.Exception ex)
        {
            socket.Close();
        }
        
    }
    public void Send(string str)
    {
        
        byte[] bytes = System.Text.Encoding.Default.GetBytes(m_name+":"+str);
        try
        {
            socket.Send(bytes);
        }
        catch { }
    }
    public static void Main(string[] args)
    {
        Console.Write("请输入你的名字:");
        string username = Console.ReadLine();
        Cli cli = new Cli(username);
        cli.Connection();
        while (true)
        {
            string str = Console.ReadLine();
            switch (str)
            {
                case "quit":
                    return;
            }
            cli.Send(str);
        }


    }

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值