Socket 1vs1 聊天工具

本文介绍了一个简单的TCP Socket通信实现,包括客户端和服务端的代码示例。客户端与服务端通过TCP协议进行连接,并能够互相发送消息。

以前没搞过Socket,今天有时间就看了一下,随便写了个小demo,只实现了基本功能,一个client,一个server,很多东西没有考虑,代码也没有加工,仅供以后学习参考。

Client

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;
using System.Net.Sockets;
using System.Threading;

namespace SocketClient
{
    public partial class Form1 : Form
    {
        private SynchronizationContext uiContext;
        private Socket client;
        private bool ConnStatus = false;
        private Thread showMsg;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnConn_Click(object sender, EventArgs e)
        {
            string ip = this.txtIP.Text;
            int port = Convert.ToInt32(this.txtPort.Text);
            IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ip), port);
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                client.Connect(ie);
                if (client.Connected)
                {
                    this.lbStatus.Text = "Connecting...";
                    this.lbStatus.ForeColor = Color.Green;
                    ConnStatus = true;
                    uiContext = SynchronizationContext.Current;
                    //单独起一个线程用于刷Message。
                    showMsg = new Thread(new ThreadStart(ShowMessage));
                    showMsg.Start();
                    this.txtSend.Enabled = true;
                    this.btnSend.Enabled = true;
                }

            }
            catch
            {
                this.lbStatus.Text = "Connect Error";
                this.lbStatus.ForeColor = Color.Red;
            }

        }

        private void ShowMessage()
        {
            byte[] data = new byte[1024];
            int recv;

            //如果连接可以,轮询接收Message并显示在文本框
            while (ConnStatus)
            {
                recv = client.Receive(data);
                string msg = Encoding.Unicode.GetString(data, 0, recv);
                //Server一旦关闭,会自动发一个exit。Client接收到之后自动关闭。
                if (msg == "exit")
                {
                    client.Shutdown(SocketShutdown.Both);
                    client.Close();
                    ConnStatus = false;
                    this.lbStatus.Text = "Disconnect";
                    txtSend.Enabled = false;
                    btnSend.Enabled = false;
                    msg = "Server is offline";
                }
                //将Message显示在文本框
                uiContext.Send((state) =>
                    {
                        rtxtMsg.AppendText(DateTime.Now.ToString() + "    <----" + "\n");
                        rtxtMsg.AppendText(msg + "\n");
                        int msglength = rtxtMsg.Text.Length;
                        rtxtMsg.Select(msglength - msg.Length - 1, msg.Length);
                        rtxtMsg.SelectionColor = Color.Red; 

                    }, null);
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtSend.Text))
            {
                client.Send(Encoding.Unicode.GetBytes(txtSend.Text));
                rtxtMsg.AppendText(DateTime.Now.ToString() + "    ---->" + "\n");
                rtxtMsg.AppendText(txtSend.Text + "\n");
                int msglength = rtxtMsg.Text.Length;
                rtxtMsg.Select(msglength - txtSend.Text.Length - 1, txtSend.Text.Length);
                rtxtMsg.SelectionColor = Color.Blue;
                txtSend.Text = string.Empty;
            }
        }

        private void btnDisconn_Click(object sender, EventArgs e)
        {
            ConnStatus = false;
            try
            {
                //Client断开连接,会先发送exit给server通知。
                client.Send(Encoding.Unicode.GetBytes("exit"));
                client.Shutdown(SocketShutdown.Both);
                client.Close();
                ConnStatus = false;
                this.lbStatus.Text = "Disconnect";
                txtSend.Enabled = false;
                btnSend.Enabled = false;
                if (showMsg.IsAlive)
                {
                    showMsg.Abort();
                }
            }
            catch
            { }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //窗口关闭时断开所有链接。
            if (client != null && client.Connected)
            {
                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
            Environment.Exit(0);
        }
    }
}
View Code

 

 Server

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.Threading;
using System.Net.Sockets;
using System.Net;

namespace SocketServer
{
    public partial class Form1 : Form
    {
        private Socket server;
        private Socket client;
        private bool clientStatus = false;
        private SynchronizationContext uiContext;
        private Thread waitConn;

        public Form1()
        {
            InitializeComponent();
            InitSocketServer();
        }

        private void InitSocketServer()
        {
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ip = new IPEndPoint(IPAddress.Any, 9050);
            server.Bind(ip);
            server.Listen(5);
            uiContext = SynchronizationContext.Current;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            //单独一个线程等待接收Client连接。
            waitConn = new Thread(new ThreadStart(WaitClient));
            waitConn.Start();
            btnStart.Enabled = false;

        }

        private void WaitClient()
        {
            client = server.Accept();
            byte[] data = new byte[1024];
            string welcome = "Welcome here!";
            data = Encoding.Unicode.GetBytes(welcome);
            client.Send(data);
            clientStatus = true;
            uiContext.Send((state) =>
            {
                rtxtMsg.AppendText(DateTime.Now.ToString() + "    ---->" + "\n");
                rtxtMsg.AppendText(welcome + "\n");
                rtxtMsg.Select(rtxtMsg.Text.Length - welcome.Length - 1, welcome.Length);
                rtxtMsg.SelectionColor = Color.Blue;
                txtSend.Enabled = true;
                btnSend.Enabled = true;

            }, null);
            //接到连接后起一个线程接收Message.
            Thread showMsg = new Thread(new ParameterizedThreadStart(ShowMessage));
            showMsg.Start(client);
        }

        private void ShowMessage(object client)
        {
            byte[] data = new byte[1024];
            Socket newClient = (Socket)client;
            int recv;
            string msg;

            //连接状态下循环接收Message.
            while (clientStatus)
            {
                recv = newClient.Receive(data);
                msg = Encoding.Unicode.GetString(data, 0, recv);
                //Client断开连接前会发exit作为通知。
                if (msg == "exit")
                {
                    clientStatus = false;
                    newClient.Shutdown(SocketShutdown.Both);
                    newClient.Close();
                    msg = "Client is offline";
                }
                uiContext.Send((state) =>
                {
                    rtxtMsg.AppendText(DateTime.Now.ToString() + "    <----" + "\n");
                    rtxtMsg.AppendText(msg + "\n");
                    rtxtMsg.Select(rtxtMsg.Text.Length - msg.Length - 1, msg.Length);
                    rtxtMsg.SelectionColor = Color.Red;

                }, null);
            }
            uiContext.Send((state) =>
            {
                txtSend.Enabled = false;
                btnSend.Enabled = false;
                btnStart.Enabled = true;

            }, null);
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtSend.Text))
            {
                byte[] msg = new byte[1024];
                msg = Encoding.Unicode.GetBytes(txtSend.Text);
                client.Send(msg);
                rtxtMsg.AppendText(DateTime.Now.ToString() + "    ---->" + "\n");
                rtxtMsg.AppendText(txtSend.Text + "\n");
                rtxtMsg.Select(rtxtMsg.Text.Length - txtSend.Text.Length - 1, txtSend.Text.Length);
                rtxtMsg.SelectionColor = Color.Blue;
                txtSend.Text = string.Empty;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //关闭窗口时断开所有链接。
            if (client != null && client.Connected)
            {
                client.Send(Encoding.Unicode.GetBytes("exit"));
                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
            if (server != null)
            {
                server.Close();
            }
            Environment.Exit(0);
        }
    }
}
View Code

转载于:https://www.cnblogs.com/Eagle0719/p/3334755.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值