网络编程-实验2-C与C通信

来源:互联网 发布:汉诺塔算法伪代码 编辑:程序博客网 时间:2024/05/22 00:30

一、实验要求

具体要求包括:

1,Server支持多客户访问;

2,C与S之间使用TCP连接;

3,C与C之间直接通信(不是通过S传递)。

4,C与C之间直接通信既可以使用TCP,也可以使用UDP。

5,可以使用Socket,也可以使用TcpClient/UdpClient等;

6,实验示意图如下:        


二、实验思路

(1)客户端登陆服务端时,打开客户端的监听并发送客户端的用户名和端口号。

(2)客户端发送信息时,服务端根据客户端的用户名返回端口号。

(3)客户端根据服务端返回的端口号与信息接收方进行tcp通信。

(4)客户端与客户端通信时,不保留连接,仅在需要发送信息时建立连接。

三、应用界面

(1)服务器界面:


(2)客户端界面(未登录):


(3)客户端界面(登陆):

 

(4)客户端与客户端互相通信:

 


 

 

(5)客户端给多个客户端发送消息:

 

(6)客户端退出:

 


源码如下:

ClientForm.cs:

using System;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.IO;using System.Threading;using System.Collections.Generic;using System.Text;namespace Client{    public partial class ClientForm : Form    {        public ClientForm()        {            InitializeComponent();            UserNameList = new List();            UserPortList = new List();            isMessageCome = false;            this.label_State.Text = "未检测到服务器";            this.FormClosing += ClientWindow_Closing;        }        private bool isMessageCome { get; set; }        private bool isLogin { get; set; }        private TcpListener listener;        private TcpClient SocketForClient;        private BinaryReader br_C;        private BinaryWriter bw_C;        private string receiveString;        private List UserNameList { get; set; }        private List UserPortList { get; set; }        private TcpClient client_S;        private NetworkStream networkStream_S;        private BinaryReader br_S;        private BinaryWriter bw_S;        private IPAddress localIpAddress;        private int remotePort;        private string remoteHost;        private string userName { get; set; }        private string userPort { get; set; }        private enum clientState        {            Login,            Talk,            Logout        };        private delegate void Delegate1();        private delegate void Delegate2();        private void ClientWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)        {            if (client_S != null)            {                SendMessageToServer(clientState.Logout, "退出服务器。", textBox_Port.Text);                br_S.Close();                bw_S.Close();                client_S.Close();            }        }        private void ClientLogin()        {            GetHostAddress();            remotePort = 51888;            remoteHost = Dns.GetHostName();            try            {                client_S = new TcpClient(remoteHost, remotePort);                this.label_State.Text = "连接服务器成功。";                NetworkStream networkStream = client_S.GetStream();                br_S = new BinaryReader(networkStream);                bw_S = new BinaryWriter(networkStream);                Thread threadReceive = new Thread(ReceiveDataFromServer);                threadReceive.IsBackground = true;                threadReceive.Start();                UpdateClientForm();                //打开监听器                listener = new TcpListener(localIpAddress, Convert.ToInt16(userPort));                listener.Start();                Thread thread_for_listener = new Thread(ReceiveClient);                thread_for_listener.IsBackground = true;                thread_for_listener.Start();            }            catch            {                //MessageBox.Show(ex.ToString());                this.label_State.Text = "服务器尚未启动,连接服务器失败。";                return;            }        }        //接收客户端与客户端之间的连接        private void ReceiveClient()        {            receiveString = null;            while (true)            {                try                {                    //MessageBox.Show("8", DateTime.Now.ToString());                    SocketForClient = listener.AcceptTcpClient();                    networkStream_S = SocketForClient.GetStream();                    bw_C = new BinaryWriter(networkStream_S);                    br_C = new BinaryReader(networkStream_S);                    receiveString = br_C.ReadString();                    //MessageBox.Show(receiveString, this.userName);                    if (receiveString != null)                    {                        Delegate1 d1 = new Delegate1(AddInfo_C);                        textBox_ReceivedMessage.Invoke(d1);                    }                    br_C.Close();                    bw_C.Close();                    networkStream_S.Close();                    SocketForClient.Close();                }                catch                {                    break;                }            }        }        //从服务器接收数据        private void ReceiveDataFromServer()        {            receiveString = null;            while (true)            {                try                {                    receiveString = br_S.ReadString();                    //MessageBox.Show("5", DateTime.Now.ToString());                    if (isUserInfo(receiveString))                    {                        //更新在线用户列表                        this.UserNameList.Clear();                        string[] s = receiveString.Split(',');                        for (int i = 0; i < s.Length - 1; i++)                        {                            if (s[i] != this.userName)                            {                                UserNameList.Add(s[i]);                            }                        }                        Delegate2 d2 = new Delegate2(AddUserToList);                        this.listBox_UserName.Invoke(d2);                    }                    else if (isUserPort(receiveString))                    {                        this.UserPortList.Clear();                        string[] s = receiveString.Split(',');                        int count = Convert.ToInt32(s[0]);                        for (int i = 0; i < count; i++)                        {                            if (s[i + 1] != this.userPort)                            {                                UserPortList.Add(s[i + 1]);                            }                        }                        string message = "";                        for (int i = count + 1; i < s.Length - 1; i++)                        {                            message += s[i];                        }                        //MessageBox.Show(message);                        for (int i = 0; i < UserPortList.Count; i++)                        {                            //MessageBox.Show(UserPortList.Count.ToString());                            SendMessageToClient(UserPortList[i], message);                        }                                            }                    else                    {                        if (textBox_ReceivedMessage.InvokeRequired)                        {                            Delegate1 d1 = new Delegate1(AddInfo_S);                            textBox_ReceivedMessage.Invoke(d1);                        }                    }                }                catch                {                    break;                }            }        }        //添加信息到面板中        private void AddInfo_S()        {            textBox_ReceivedMessage.Text += DateTime.Now.ToString() + " Server:" + receiveString + "\r\n";        }        private void AddInfo_C()        {            string[] s = receiveString.Split(',');            StringBuilder sb = new StringBuilder();            for (int i = 1; i < s.Length; i++)            {                sb.Append(s[i]);            }            textBox_ReceivedMessage.Text += DateTime.Now.ToString() + " " + s[0] + ":" + sb.ToString() + "\r\n";        }        //添加信息到在线用户面板中        private void AddUserToList()        {            this.listBox_UserName.Items.Clear();            foreach (string name in UserNameList)            {                this.listBox_UserName.Items.Add(name);            }        }        //判断是否是用户信息        private bool isUserInfo(string receiveString)        {            string[] s = receiveString.Split(',');            if (s[s.Length - 1] == "@UserName")            {                return true;            }            return false;        }        //判断是否是用户端口号        private bool isUserPort(string receiveString)        {            string[] s = receiveString.Split(',');            if (s[s.Length - 1] == "@UserPort")            {                return true;            }            return false;        }        //发送状态和信息        //重载1,启动状态和离开状态        private void SendMessageToServer(clientState state, string message, string port)        {            try            {                if (message != "" && port != "")                {                    switch (state)                    {                        case clientState.Login:                            bw_S.Write("Login," + textBox_UserName.Text + "," + port);                            break;                        case clientState.Logout:                            bw_S.Write("Logout," + message);                            break;                        default:                            break;                    }                    bw_S.Flush();                }            }            catch { return; }        }        //重载2,交流状态        private void SendMessageToServer(clientState state, List list, string message)        {            try            {                if (clientState.Talk == state && list.Count > 0 && message != "")                {                    //MessageBox.Show("2", DateTime.Now.ToString());                    bw_S.Write("Talk," + GetUserNameFromListBox(list) + message);                    bw_S.Flush();                }            }            catch { return; }        }        //获取需要列表中选中的用户名        private string GetUserNameFromListBox(List list)        {            string names = "";            int i = list.Count;            names = i.ToString() + ",";            foreach (string name in list)            {                names += name + ",";            }            return names;        }        public void UpdateClientForm()        {            this.textBox_IPAddress.Text = localIpAddress.ToString();            this.userName = textBox_UserName.Text;            this.userPort = textBox_Port.Text;        }        private void GetHostAddress()        {            IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());            foreach (var v in ips)            {                if (v.AddressFamily == AddressFamily.InterNetwork)                {                    localIpAddress = v;                    break;                }            }        }        //判断信息传送对象        private List GetListBoxSelectedItems(ListBox listBox_UserName)        {            List list = new List();            for (int i = 0; i < listBox_UserName.SelectedItems.Count; i++)            {                list.Add(listBox_UserName.SelectedItems[i].ToString());            }            return list;        }        private void btn_SendMessage_Click(object sender, EventArgs e)        {            if (isLogin)            {                //MessageBox.Show("1", DateTime.Now.ToString());                SendMessageToServer(clientState.Talk, GetListBoxSelectedItems(this.listBox_UserName), this.textBox_SendMessage.Text);                textBox_SendMessage.Clear();            }        }        //根据端口号发送信息        private void SendMessageToClient(string userPort, string message)        {            try            {                //MessageBox.Show("7", DateTime.Now.ToString());                TcpClient c = new TcpClient(remoteHost, Convert.ToInt32(userPort));                NetworkStream networkStream = c.GetStream();                BinaryWriter bw = new BinaryWriter(networkStream);                BinaryReader br = new BinaryReader(networkStream);                bw.Write(this.userName + "," + message);                bw.Flush();                bw.Close();                br.Close();                networkStream.Close();                c.Close();                //MessageBox.Show("关闭流");            }            catch            {                MessageBox.Show("error 01");            }        }        private void btn_Login_Click(object sender, EventArgs e)        {            if (textBox_UserName.Text != "" && textBox_Port.Text != "")            {                ClientLogin();                SendMessageToServer(clientState.Login, userName, userPort);                textBox_UserName.Enabled = false;                textBox_Port.Enabled = false;                btn_Login.Enabled = false;                isLogin = true;            }        }        private void ClientForm_Load(object sender, EventArgs e)        {        }    }}

ServerForm.cs :

using System;using System.Collections.Generic;using System.Windows.Forms;using System.Net.Sockets;using System.Net;using System.Threading;using Client;namespace Server{    public partial class ServerForm : Form    {        //Variables6        public static IPAddress localIpAddress;        public static int port = 51888;        private TcpListener myListener;        private TcpClient SocketForClient;        private NetworkStream networkStream;        private Thread myThread;        private string message;        private delegate void delegate1();        private delegate void delegate_AddInfo();        //Attributes        //Functions        public ServerForm()        {            InitializeComponent();            this.Closing += ThreadServer_Closing;            try            {                GetHostAddress();                UpdateServerForm();                OpenTcpListener();                OpenOtherListener();            }            catch (Exception ex)            {                MessageBox.Show(ex.ToString());                MessageBox.Show("服务器初始化失败", "提示");            }        }        //后台检测需不需要更新面板        private void UpdateInfoListener()        {            while (true)            {                while (CC.updated == true)                {                    delegate1 d = new delegate1(UpdateClientList);                    this.dataGridView1.Invoke(d);                    CC.updated = false;                }            }        }        //后台检测功能        private void OpenOtherListener()        {            Thread messageListener = new Thread(MessageListener);            messageListener.IsBackground = true;            messageListener.Start();            Thread updateInfoListener = new Thread(UpdateInfoListener);            updateInfoListener.IsBackground = true;            updateInfoListener.Start();        }        //后台检测是否有信息需要输出到message面板中        private void MessageListener()        {            while (true)            {                while (CC.messageQueue.Count > 0)                {                    message = CC.messageQueue.Dequeue();                    delegate_AddInfo delegate1 = new delegate_AddInfo(AddInfo);                    textBox_ReceivedMessage.Invoke(delegate1);                }            }        }        private void AddInfo()        {            this.textBox_ReceivedMessage.Text += message + "\r\n";        }        //获取本机地址        private void GetHostAddress()        {            IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());            foreach (var v in ips)            {                if (v.AddressFamily == AddressFamily.InterNetwork)                {                    localIpAddress = v;                    break;                }            }        }        //更新服务器面板部分信息        public void UpdateServerForm()        {            this.textBox_IPAddress.Text = localIpAddress.ToString();            this.textBox_Port.Text = port.ToString();        }        //开启tcp监听器        private void OpenTcpListener()        {            try            {                myListener = new TcpListener(localIpAddress, port);                myListener.Start();                label_State.Text = string.Format("开始在{0}:{1}监听客户连接", localIpAddress, port);                myThread = new Thread(ListenClientConnection);                myThread.IsBackground = true;                myThread.Start();            }            catch (Exception ex)            {                MessageBox.Show(ex.ToString());                label_State.Text = "服务器启动监听失败,请尝试重新启动。";            }        }        //tcp监听器        private void ListenClientConnection()        {            while (true)            {                try                {                    SocketForClient = myListener.AcceptTcpClient();                    networkStream = SocketForClient.GetStream();                    User user = new User(SocketForClient);                    CC.userList.Add(user);                    user.ReceiveData();                    delegate1 d = new delegate1(UpdateClientList);                    this.dataGridView1.Invoke(d);                    CC.SendToClient(user, "Hello!");                }                catch                {                    break;                }            }        }        //客户端关闭的时候        private void ThreadServer_Closing(object sender, System.ComponentModel.CancelEventArgs e)        {            if (myListener != null)            {                if (SocketForClient != null)                {                    SocketForClient.Close();                    networkStream.Close();                }                myListener.Stop();                this.label_State.Text = "服务器已关闭";            }        }        //添加在线用户到数组中        private void AddClientToCC()        {            CC.Count = 0;            foreach (DataGridViewRow dr in this.dataGridView1.Rows)            {                CC.Count++;            }            CC.Count--;            int i = 0;            foreach (DataGridViewRow dr in this.dataGridView1.Rows)            {                if (i < CC.Count)                {                    CC.userNamePort[i, 0] = dr.Cells[0].Value.ToString();                    CC.userNamePort[i, 1] = dr.Cells[1].Value.ToString();                    i++;                }            }        }        //更新客户端列表        private void UpdateClientList()        {            if (CC.userList.Count > 0)            {                try                {                    this.dataGridView1.Rows.Clear();                    System.Threading.Thread.Sleep(1000);                    //创建表的行,并与表相关联。                    foreach (User user in CC.userList)                    {                        DataGridViewRow dr = new DataGridViewRow();                        dr.CreateCells(dataGridView1);                        dr.Cells[0].Value = user.UserName;                        dr.Cells[1].Value = user.UserPort;                        this.dataGridView1.Rows.Add(dr);                    }                    AddClientToCC();                    //发送消息给所有客户端以更新用户列表信息                    CC.UpdateClientList(CC.userList);                }                catch (Exception ex)                {                    MessageBox.Show(ex.ToString());                }            }            else            {                this.dataGridView1.Rows.Clear();            }        }        //发送消息的按钮事件        private void btn_SendMessage_Click(object sender, EventArgs e)        {            if (this.textBox_SendMessage.Text != "")            {                string sendMessage = this.textBox_SendMessage.Text;                List selectedUser = new List();                foreach (User user in CC.userList)                {                    //遍历选中的行对象                    foreach (DataGridViewRow dr in this.dataGridView1.SelectedRows)                    {                        //判断是否存在于user列表中                        if (dr.Cells[0].Value.ToString() == user.UserName && dr.Cells[1].Value.ToString() == user.UserPort)                        {                            selectedUser.Add(user);                            break;                        }                    }                }                CC.SendToClient(selectedUser, sendMessage);                this.textBox_SendMessage.Text = "";            }        }        //创建客户端        private void btn_CreateClient_Click(object sender, EventArgs e)        {            ClientForm cForm = new ClientForm();            cForm.Show();        }        private void ServerForm_Load(object sender, EventArgs e)        {        }        private void btn_Flush_Click(object sender, EventArgs e)        {            UpdateClientList();        }    }}

CC.cs:

using System;using System.Collections.Generic;using System.Windows.Forms;namespace Server{    public class CC    {        public static List userList { get; set; }        public static Queue messageQueue { get; set; }        public static Dictionary Users { get; set; }        public static bool updated { get; set; }        public static string[,] userNamePort { get; set; }        public static int Count { get; set; }        static CC()        {            userList = new List();            userNamePort = new string[100,2];            messageQueue = new Queue();            Users = new Dictionary();        }        public static void SendToServer(string message)        {            messageQueue.Enqueue(message);        }        public static void RemoveUser(User user)        {            userList.Remove(user);        }        public static void SendToClient(List selectedUser, string message)        {            foreach (User user in selectedUser)            {                user.bw.Write(message);                user.bw.Flush();            }        }        public static void SendToClient(User selectedUser, string message)        {            //MessageBox.Show("4", DateTime.Now.ToString());            selectedUser.bw.Write(message);            selectedUser.bw.Flush();        }        //更新用户信息列表        public static void UpdateClientList(List selectedUser)        {            string info = "";            foreach (User user in selectedUser)            {                info += user.UserName + ",";            }            info += "@UserName";            foreach (User user in selectedUser)            {                user.bw.Write(info);                user.bw.Flush();            }        }        internal static void SendToClient(string message)        {            throw new NotImplementedException();        }    }}

User.cs:
using System;using System.Collections.Generic;using System.IO;using System.Net.Sockets;using System.Text;using System.Threading;using System.Windows.Forms;namespace Server{    public class User    {        public BinaryReader br { get; private set; }        public BinaryWriter bw { get; private set; }        public string receiveString { get; set; }        public bool isRead { get; set; }        private TcpClient client;        private NetworkStream networkStream;        private Thread IOThread;        private delegate void delegateAddInfo();        private string mmessage;        public string UserName;        public string UserPort;        public User(TcpClient client)        {            this.client = client;            networkStream = client.GetStream();            br = new BinaryReader(this.networkStream);            bw = new BinaryWriter(this.networkStream);        }        public void ReceiveData()        {            IOThread = new Thread(ReceiveFromClient);            IOThread.Start();        }        //接收信息        private void ReceiveFromClient()        {            while (true)            {                receiveString = null;                try                {                    receiveString = br.ReadString();                }                catch                {                    CC.RemoveUser(this);                    return;                }                string[] split = receiveString.Split(',');                switch (split[0])                {                    case "Login":                        UserName = split[1];                        UserPort = split[split.Length - 1];                        mmessage = DateTime.Now.ToString() + " " + UserName + "[" + UserPort + "]" + "成功连接服务器。";                        break;                    case "Talk":                        mmessage = DateTime.Now.ToString() + " " + UserName + "[" + UserPort + "]" + GetMessage(receiveString);                        break;                    case "Logout":                        mmessage = DateTime.Now.ToString() + " " + UserName + "[" + UserPort + "]" + "已与服务器断开。";                        //删除并更新面板                        CC.RemoveUser(this);                        CC.updated = true;                        CC.UpdateClientList(CC.userList);                        break;                    default:                        break;                }                CC.SendToServer(mmessage);            }        }        //处理信息中的用户信息,查看转发对象。        private List SendMessageToWho(string receiveString)        {            List users = new List();            string[] s = receiveString.Split(',');            try            {                int number = Convert.ToInt32(s[1]);                if (number > 0)                {                    for (int i = 0, j = 2; i < number; i++, j++)                    {                        users.Add(s[j]);                    }                }                return users;            }            catch { return null; }        }        //处理信息        private string GetMessage(string receviceString)        {            //MessageBox.Show("3", DateTime.Now.ToString());            string[] s = receviceString.Split(',');            StringBuilder sb = new StringBuilder();            StringBuilder sb_Return = new StringBuilder();            List list = SendMessageToWho(receiveString);            sb.Append("向");            sb_Return.Append(list.Count.ToString() + ",");            for (int i = 0; i < list.Count; i++)            {                sb.Append(list[i] + ",");                sb_Return.Append(GetUserPort(list[i]) + ",");            }            sb.Append("发送了消息:");            for (int i = list.Count + 2; i < s.Length; i++)            {                sb.Append(s[i]);                sb_Return.Append(s[i]);            }            sb_Return.Append(",@UserPort");            CC.SendToClient(this,sb_Return.ToString());            return sb.ToString();        }        private string GetUserPort(string UserName)        {            for(int i = 0;i




 

1 0
原创粉丝点击