使用Socket模拟聊天室

前言

Socket 是对 TCP/IP 协议的封装,Socket 只是个接口不是协议,通过 Socket 我们才能使用 TCP/IP 协议,除了 TCP,也可以使用 UDP 协议来传递数据。

 本文不对TCP/IP进行深入理解阐释,仅仅针对WinForm中如何使用Socket的几个关键点进行阐述。

Server

采用的是C/S架构,在某一时刻,服务器只能与一个客户端建立连接。

1、初始化,将本地IP作为Server的IP地址,端口号可以随意指定。
  public ServerForm()
        {
            InitializeComponent();
            IPAddress[] localIP = Dns.GetHostAddresses(Dns.GetHostName());      //Get any IP
            foreach (IPAddress address in localIP)
            {
                if (address.AddressFamily == AddressFamily.InterNetwork)
                {
                    tb_IPAdress.Text = address.ToString();
                }
            }
        }
2、创建监听实例,启动Server
private void StartServer_button_Click(object sender, EventArgs e)
        {
            new System.Threading.Thread(s =>
            {
                try
                {
                    TcpListener listener = new TcpListener(IPAddress.Any, int.Parse(textBox5.Text));
                    listener.Start();
                    client = listener.AcceptTcpClient();
                    strRead = new StreamReader(client.GetStream());
                    strWrite = new StreamWriter(client.GetStream());
                    strWrite.AutoFlush = true;

                    Listen_backgroundWorker.RunWorkerAsync();                         //Start recieving data 
                    Listen_backgroundWorker.WorkerSupportsCancellation = true;  
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message.ToString());
                }
            })
            { IsBackground = true }.Start();
        }

如代码所示,新建了一个线程——线程启动了一个指定IP地址和端口号的服务端,并开始监听读写请求。如下的Listen_backgroundWorker线程,则对接收到的消息在UI上进行显示:

 private void Listen_backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (client.Connected)
            {
                try
                {
                    recieve = strRead.ReadLine();
                    this.Receive_textBox.Invoke(new MethodInvoker(delegate () { Receive_textBox.AppendText("C发送 : " + recieve + "\n"); }));
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message.ToString());
                }
            }
        }
3、Server向已与之建立连接的Client发送消息:
 private void Send_button_Click(object sender, EventArgs e)
        {
            if (SendtextBox.Text != "")
            {
                textToSend = SendtextBox.Text;
                Send_backgroundWorker.RunWorkerAsync();
            }
            SendtextBox.Text = "";
        }

private void Send_backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { if (client.Connected) { strWrite.WriteLine(textToSend); this.Receive_textBox.Invoke(new MethodInvoker(delegate () { Receive_textBox.AppendText("S发送 : " + textToSend + "\n"); })); } else { MessageBox.Show("Send Failed!"); } Send_backgroundWorker.CancelAsync(); }
 

Client

1、将Client连接至指定IP地址和端口号Server。
        private void ConnectToServer_button_Click(object sender, EventArgs e)
        {           
            try
            {
                client = new TcpClient();
                IPEndPoint ip_End = new IPEndPoint(IPAddress.Parse(textBox6.Text), int.Parse(textBox4.Text));
                client.Connect(ip_End);
                if (client.Connected)
                {
                    Receive_textBox.AppendText("Connected to server" + "\n");
                    stw = new StreamWriter(client.GetStream());
                    str = new StreamReader(client.GetStream());
                    stw.AutoFlush = true;      
                    Receive_backgroundWorker.RunWorkerAsync();
                }
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message.ToString());
            }
        }

如下代码,在Client连接的到Server之后,也开始可以随时接收由Server传来的消息:

        private void Receive_backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (client.Connected)
            {
                try
                {
                    recieve = str.ReadLine();
                    this.Receive_textBox.Invoke(new MethodInvoker(delegate () { Receive_textBox.AppendText("S发送 : " + recieve + "\n"); }));
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message.ToString());
                }
            }
        }
2、与Server建立连接的Client可以随时发送消息:
  private void Send_button_Click(object sender, EventArgs e)
        {
            if (Send_textBox.Text != "")
            {
                textToSend = Send_textBox.Text;
                Send_backgroundWorker.RunWorkerAsync();
            }
            Send_textBox.Text = "";
        }

 private void Send_backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (client.Connected)
            {
                stw.WriteLine(textToSend);
                this.Receive_textBox.Invoke(new MethodInvoker(delegate () { Receive_textBox.AppendText("C发送 :  " + textToSend + "\n"); }));
            }
            else
            {
                MessageBox.Show("Send Failed!");
            }
            Send_backgroundWorker.CancelAsync();
        }

运行结果:

 

 源码:https://github.com/Deskew/SocketChat

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值