网络编程-实验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; ListselectedUser = 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 ListuserList { 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 ListSendMessageToWho(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
- 网络编程-实验2-C与C通信
- 网络编程-实验1-C与S通信
- [Linux C编程]网络通信
- socket编程 与c通信
- [Linux C编程]TCP网络通信
- [Linux C编程]TCP网络通信
- [Linux C编程]UDP网络通信
- C-S通信实验
- 通信网络实验-socket编程
- Linux下TCP网络编程与基于Windows下C#Socket编程间通信
- 【网络编程6】Java与C语言套接字Socket通信的例子
- C#:网络通信(TCP)
- Linux C——网络编程传输文件的实验
- C编程之基于UDP的网络通信
- Linux 下 C 网络编程之 多线程通信 实例
- java网络编程之一对一的socket C/S通信
- Linux 下 C 网络编程之 多线程通信 实例
- C#TCP Socket网络编程(异步通信方式)
- Win7下Nginx的安装与配置,win7nginx配置
- Matlab图像预处理命令
- android绘制动画实现方式
- iOS Apps – JSON-RPC – Go Servers
- JWT简介
- 网络编程-实验2-C与C通信
- 这是个开端
- LeetCode (16)3Sum Closest
- 安装office2016碰到的问题 error 1402
- 内核编译过程:linux-3.0.8
- BeanFactory【了解】
- 代码量统计
- 程序员的基础生存技能:高效用Google
- windows错误:microsoft runtime dll 安装程序未能安装