• 异步Socket编写的一个简易的聊天室


    异步Socket的一点心得,代码注释的很完善。希望对还不太熟悉Socket的网友有点帮助,哪怕是一点点就可以了。
    不说了,先截图吧

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Windows.Forms;
    namespace WindowsApplication1
    {
        
    class MySocket
        {
            
    private string ip = null;
            
    private int port = 0;
            
    public Socket TcpSocket = null//这里定义Public级别是为在类外访问
            public byte[] bb = new byte[1024];
            
    int num = 0;
            
    public TextBox tx;
            
    public MySocket(string ip, int port)
            {
                
    this.ip = ip;
                
    this.port = port;
            }
            
    public string Ip
            {
                
    get { return ip; }
                
    set { ip = value; }
            }
            
    public int Port
            {
                
    get { return port; }
                
    set { port = value; }
            }
            
    ///<summary>
            
    ///设置终结点,并用异步来接收传过来的Socket对象
            
    ///</summary>
            public void GetSocket()
            {
                
    //用Parse方法转换字符
                IPAddress ipname = IPAddress.Parse(ip);
                
    //设置终结点,为以后Socket绑定做准备
                IPEndPoint iphost = new IPEndPoint(ipname, Port);
                
    //我用Tcp协议,所以用SocketType.Stream,如果你用Udp,那么请用SocketType.Dgram
                Socket mysock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                mysock.Bind(iphost); 
    //绑定,这是Socket基本用法
                mysock.Listen(100);   //开始监听
                
    //这个异步表示如果mysock一旦发现有客户断连接,那么异步方法将会被立即调用
                
    //有很多网友称之为“启动后不管”
                mysock.BeginAccept(new AsyncCallback(Shu), mysock);
            }

            
    public void Shu(IAsyncResult e)
            {
                Socket s 
    = (Socket)e.AsyncState;//这里是异步的通用做法,用异步接口的AsyncState返回自身
                TcpSocket = s.EndAccept(e);//这里是接收的真正的异步Socket对象
                
    //下面继续用异步接收信息,之所以用异步接收,是因为程序
                
    //运行在UI里面,以妨程序出现假死状态,后面我将会用线程来控制这个问题
                AsyncCallback mm = new AsyncCallback(GetShu);
                TcpSocket.BeginReceive(bb, 
    0, bb.Length, SocketFlags.None, mm, TcpSocket);//这里把自身做为参数给下个异步方法调用
                s.BeginAccept(new AsyncCallback(Shu), s);
            }
            
    //这里创建代表是用于在UI线程上设置TextBox的值,因为线程Id值不一样,所以必须用BeginInvoke设置
            public delegate void MyDeleTe(string txt);
            
    public void SetTxt(string txt)
            {
                
    if (tx.InvokeRequired)  //这里其实是多余的,但它可以防止不是同一线城的设置
                {
                    tx.BeginInvoke(
    new MyDeleTe(SetTxt), txt);
                }
                
    else
                {
                    tx.Text 
    += "\r\n"+ txt;
                }
            }
            
    public void GetShu(IAsyncResult e)
            {
                Socket list 
    = (Socket)e.AsyncState;
                
    //我想解释一下为什么EndReceive(e);后的返回对象都不一样
                
    //比如Socket返回的是Socket对象,而接收信息返回的是int对象呢?
                
    //因为那是因为调用这个方法返回的值。比如Receive方法返回是int,所以异步也返回int.
                num = list.EndReceive(e);
                
    string message = "Client say:";
                
    if (num > 0)
                {
                    message
    +=Encoding.ASCII.GetString(bb, 0, num);// message是返回的Client发来的信息
                    tx.BeginInvoke(new MyDeleTe(SetTxt), message.ToString());
                }
            }
        }
    }
    由于时间关系,只做了个服务器端类异步程序,代码如上所示。调用非常简单,只需
      private void Form1_Load(object sender, EventArgs e)
            {
                
    string ip = "127.0.0.1";
                
    int port = 2000;
                MySocket mm 
    = new MySocket(ip, port);
                mm.tx 
    = txtserver;
                mm.GetSocket();
            }
    欢迎大家讨论.
  • 相关阅读:
    【JAVA SE基础篇】49.文件字符流和字节数组流
    【JAVA SE基础篇】48.IO流四大抽象类介绍和字节流
    【JAVA SE基础篇】47.file类的方法
    【JAVA SE基础篇】46.IO流的介绍
    【HTML篇】4.HTML的内嵌标签、框架标签、表单
    【HTML篇】3.HTML的图片标签、超链接标签、表格标签
    【HTML篇】2.HTML的head标签和body标签
    【HTML篇】1.HTML的介绍、三大基石、标准文档结构
    【JAVA SE基础篇】45.迭代器、Collections工具类以及使用容器存储表格
    【JAVA SE基础篇】44.手工实现简易HashMap和HashSet
  • 原文地址:https://www.cnblogs.com/xuting/p/1544381.html
Copyright © 2020-2023  润新知