TCP应用编程

使用socket可以连接到服务器,收发数据。

首先要建立服务器端,在服务器端建立用户类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace SyncChatServer
{
    class User
    {
        public TcpClient client {get;private set; }
        public BinaryReader br { get; private set; }
        public BinaryWriter bw { get; private set; }
        public string username { get; set; }
        public User(TcpClient client)
        {
            this.client = client;
            NetworkStream networkStream = client.GetStream();
            br = new BinaryReader(networkStream);
            bw = new BinaryWriter(networkStream);
        }
        public void Close()
        {
            br.Close();
            bw.Close();
            client.Close();
        }
    }
}

下边建立服务器端

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 SyncChatServer
{
    public partial class MainForm : Form
    {
        /// <summary>保存连接的所有用户</summary>
        private List<User> userList = new List<User>();
        /// <summary>使用本地的IP地址</summary>
        IPAddress localAddress;
        /// <summary>监听窗口</summary>
        private const int port = 51888;
        private TcpListener myListener;
        /// <summary>是否正常退出所有接收线程</summary>
        bool isNormalExit = false;
        public MainForm()
        {
            InitializeComponent();
            listBox1.HorizontalScrollbar = true;
            IPAddress[] addrIP = Dns.GetHostAddresses(Dns.GetHostName());
            localAddress=addrIP[0];
            buttonStop.Enabled = false;
        }


        private void buttonStart_Click(object sender, EventArgs e)
        {
            myListener = new TcpListener(localAddress,port);
            myListener.Start();
            AddItemToListBox(string.Format("开始在{0}:{1}监听客户连接",localAddress,port));
            //创建一个线程监听客户端连接请求
            Thread myThread = new Thread(ListenClientConnect);
            myThread.Start();
            buttonStart.Enabled = false;
            buttonStop.Enabled = true;
        }
        private void ListenClientConnect()
        {
            TcpClient newClient = null;
            while (true)
            {
                try
                {
                    newClient = myListener.AcceptTcpClient();
                }
                catch
                {
                    break;
                }
                User user = new User(newClient);
                Thread threadReceive = new Thread(ReceiveData);
                threadReceive.Start(user);
                userList.Add(user);
                AddItemToListBox(string.Format("[{0}]进入",newClient.Client.RemoteEndPoint));
                AddItemToListBox(string.Format("当前连接用户数:{0}",userList.Count));
            }
        }
        /// <summary>
        /// 处理接收的客户端数据
        /// </summary>
        /// <param name="userState">客户端信息</param>
        private void ReceiveData(object userState)
        {
            User user = (User)userState;
            TcpClient client = user.client;
            while (isNormalExit == false)
            {
                string receiveString = null;
                try
                {
                    //从网络流中读出字符串,此方法会自动判断字符串长度前缀
                    receiveString = user.br.ReadString();
                }
                catch
                {
                    if (isNormalExit == false)
                    {
                        AddItemToListBox(string.Format("与{0}失去联系,已终止接收该用户信息",client.Client.RemoteEndPoint));
                        RemoveUser(user);
                    }
                    break;
                }
                AddItemToListBox(string.Format("来自[{0}]:[{1}]",user.client.Client.RemoteEndPoint,receiveString));
                string[] splitString = receiveString.Split(',');
                switch(splitString[0])
                {
                    case "Login":
                        user.username = splitString[1];
                        SendToAllClient(user,receiveString);
                        break;
                    case "Logout":
                        SendToAllClient(user,receiveString);
                        RemoveUser(user);
                        return;
                    case "Talk":
                        string talkString = receiveString.Substring(
                            splitString[0].Length + splitString[1].Length+2);
                        AddItemToListBox(string.Format("{0}对{1}说 {2}",user.username,splitString[1],talkString));
                        foreach (User target in userList)
                        {
                            if (target.username == splitString[1] && user.username != splitString[1])
                            {
                                SendToClient(target,"talk,"+user.username+","+talkString);
                            }
                        }
                        break;
                    default:
                        AddItemToListBox("什么意思:"+receiveString);
                        break;

                }
            }
        }
        /// <summary>
        /// 发送message给user
        /// </summary>
        /// <param name="user"></param>
        /// <param name="message"></param>
        private void SendToClient(User user,string message)
        {
            try
            {
                user.bw.Write(message);
                user.bw.Flush();
                AddItemToListBox(string.Format("向[{0}]发送:{1}", user.username, message));
            }
            catch
            {
                AddItemToListBox(string.Format("向[{0}]发送信息失败",user.username));
            }
        }
        /// <summary>
        /// 发送信息给所有用户
        /// </summary>
        /// <param name="user"></param>
        /// <param name="message"></param>
        private void SendToAllClient(User user,string message)
        {
            string command = message.Split(',')[0].ToLower();
            if (command == "login")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    SendToClient(userList[i],message);
                    if (userList[i].username != user.username)
                    {
                        SendToClient(user,"login,"+userList[i].username);
                    }
                }
            }
            else if (command == "logout")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    if (userList[i].username != user.username)
                    {
                        SendToClient(userList[i], message);
                    }
                }
            }
        }

       
        /// <summary>
        /// 移除用户
        /// </summary>
        /// <param name="user"></param>
        private void RemoveUser(User user)
        {
            userList.Remove(user);
            user.Close();
            AddItemToListBox(string.Format("当前连接用户数:{0}",userList.Count));
        }
        private delegate void AddItemToListenBoxDelegate(string str);
        /// <summary>
        /// 追加信息
        /// </summary>
        /// <param name="str"></param>
        private void AddItemToListBox(string str)
        {
            if (listBox1.InvokeRequired)
            {
                AddItemToListenBoxDelegate d = AddItemToListBox;
                listBox1.Invoke(d, str);
            }
            else
            {
                listBox1.Items.Add(str);
                listBox1.SelectedIndex = listBox1.Items.Count - 1;
                listBox1.ClearSelected();
            }
        }
        /// <summary>【停止监听】按钮的Click事件 </summary>
        private void buttonStop_Click(object sender, EventArgs e)
        {
            AddItemToListBox("开始停止服务,并依次使用户退出!");
            isNormalExit = true;
            for (int i = userList.Count - 1; i >= 0;i-- )
            {
                RemoveUser(userList[i]);
            }
        }

        private void MainForm_FormClosing(object sender, FormClosedEventArgs e)
        {
            if (myListener != null)
            {
                buttonStop.PerformClick();
            }
        }

       

        
    }
}

客户端代码

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

namespace SyncChatClient
{
    public partial class Form1 : Form
    {
        private bool isExit = false;
        private TcpClient client;
        private BinaryReader br;
        private BinaryWriter bw;
        public Form1()
        {
            InitializeComponent();
            Random r = new Random((int)DateTime.Now.Ticks);
            textBoxUserName.Text = "user" + r.Next(100,999);
            listBoxOnlineStatus.HorizontalScrollbar = true;
        }
        /// <summary>
        /// 【连接服务器】按钮的Click事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonConnect_Click(object sender, EventArgs e)
        {
            buttonConnect.Enabled = false;
            try
            {
                client = new TcpClient(Dns.GetHostName(), 51888);
                AddTalkMessage("连接成功");
            }
            catch
            {
                AddTalkMessage("连接失败");
                buttonConnect.Enabled = true;
                return;
            }
            //获取网络流
            NetworkStream networkStream = client.GetStream();
            //将网络流作为二进制读写对象
            br = new BinaryReader(networkStream);
            bw = new BinaryWriter(networkStream);
            SendMessage("Login,"+textBoxUserName.Text);
            Thread threadReceive = new Thread(new ThreadStart(ReceiveData));
            threadReceive.IsBackground = true;
            threadReceive.Start();
        }
        /// <summary>处理接收的服务器端数据</summary>
        private void ReceiveData()
        {
            string receiveString = null;
            while (isExit == false)
            {
                try
                {
                    receiveString = br.ReadString();
                }
                catch
                {
                    if (isExit == false)
                    {
                        MessageBox.Show("与服务器失去联系。");
                    }
                    break;
                }
                string[] splitString = receiveString.Split(',');
                string command = splitString[0].ToLower();
                switch (command)
                {
                    case "login":
                        AddOnline(splitString[1]);
                        break;
                    case "logout":
                        RemoveUserName(splitString[1]);
                        break;
                    case "talk":
                        AddTalkMessage(splitString[1] + ": \r\n");
                        AddTalkMessage(receiveString.Substring(
                            splitString[0].Length + splitString[1].Length + 2));
                        break;
                    default:
                        AddTalkMessage("什么意思:" + receiveString);
                        break;
                }
            }
            Application.Exit();

        }
        /// <summary>向服务器端发送消息</summary>
        private void SendMessage(string message)
        {
            try
            {
                //将字符串写入网络流,此方法会自动附加字符串长度前缀
                bw.Write(message);
                bw.Flush();
            }
            catch
            {
                AddTalkMessage("发送失败");
            }
        }
        /// <summary>【发送】按钮的Click事件</summary>
        private void buttonSend_Click(object sender, EventArgs e)
        {
            if (listBoxOnlineStatus.SelectedIndex != -1)
            {
                SendMessage("Talk," + listBoxOnlineStatus.SelectedItem + "," + textBox2.Text + "\r\n");
                textBox2.Clear();
            }
            else
            {
                MessageBox.Show("请先在(当前在线)中选择一个对话者");
            }
        }
        /// <summary>关闭窗口时触发的事件</summary>
        private void Form1_Closing(object sender, FormClosingEventArgs e)
        {
            //未与服务器连接前client为null
            if (client != null)
            {
                SendMessage("Logout," + textBoxUserName.Text);
                isExit = true;
                br.Close();
                bw.Close();
                client.Close();
            }
        }
        /// <summary>在发送消息文本框按下【Enter】键触发的事件</summary>
        private void textBoxSend_KeyPress(object sender,KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Return)
            {
                buttonSend.PerformClick();
            }
        }
        private delegate void MessageDelegate(string message);
        /// <summary>在richTextBoxTalkInfo中追加聊天信息</summary>
        private void AddTalkMessage(string message)
        {
            if (richTextBoxTalkInfo.InvokeRequired)
            {
                MessageDelegate d = new MessageDelegate(AddTalkMessage);
                richTextBoxTalkInfo.Invoke(d, new object[] { message });
            }
            else
            {
                richTextBoxTalkInfo.AppendText(message+Environment.NewLine);
                richTextBoxTalkInfo.ScrollToCaret();
            }
        }
        private delegate void AddOnlineDelegate(string message);
        /// <summary>在listBoxOnlineStatus中添加在线的其他客户端信息</summary>
        private void AddOnline(string userName)
        {
            if (listBoxOnlineStatus.InvokeRequired)
            {
                AddOnlineDelegate d = new AddOnlineDelegate(AddOnline);
                richTextBoxTalkInfo.Invoke(d, new object[] { userName });
            }
            else
            {
                listBoxOnlineStatus.Items.Add(userName);
                listBoxOnlineStatus.SelectedIndex = listBoxOnlineStatus.Items.Count - 1;
                listBoxOnlineStatus.ClearSelected();
            }
        }
        private delegate void RemoveUserNameDelegate(string userName);
        /// <summary>在listBoxOnlineStatus中移除不在线的其他客户端信息</summary>
        private void RemoveUserName(string userName)
        {
            if (listBoxOnlineStatus.InvokeRequired)
            {
                RemoveUserNameDelegate d = RemoveUserName;
                listBoxOnlineStatus.Invoke(d, userName);
            }
            else
            {
                listBoxOnlineStatus.Items.Remove(userName);
                listBoxOnlineStatus.SelectedIndex = listBoxOnlineStatus.Items.Count - 1;
                listBoxOnlineStatus.ClearSelected();
            }
        }
    }
}

先运行服务器端后运行客户端

原文地址:https://www.cnblogs.com/zhangyuefen/p/3036101.html