1、四、需要完成的内容需要有基本的双人、多人文字聊天功能,上下线通知,在线用户列表,点对点文件传输,所有的文字或文件传输需支持CRC-32校验,具有出错重传机制。五、设计步骤在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model)。该模式的建立基于以下两点:(1)非对等作用;(2)通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式:1、首先服务器方要先启动,并根据请示提供相应服务,其过程如下:(1)打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。(2)等待客户请求到达该端口。(3)接收到重复服务请求,处理
2、该请求并发送应答信号。(4)返回第二步,等待另一客户请求(5)关闭服务器。2、客户方:(1)打开一通信通道,并连接到服务器所在主机的特定端口。(2)向服务器发送服务请求报文,等待并接收应答;继续提出请求(3)请求结束后关闭通信通道并终止。3、TCP连接的套接字的系统调用时序图如图2.1所示。4、TCP连接的应用程序流程图如图2.2所示。六、设计报告要求见课程设计报告图2.1 TCP连接的套接字的系统调用时序图图2.2 TCP连接的应用程序流程图 七、实验代码(1)客户机模式:using System;using System.Windows.Forms;/添加的命名空间引用using Syst
3、em.Net;using System.Net.Sockets;using System.Threading;using System.IO;namespace SyncChatClient public partial class MainForm : Form private bool isExit = false; private TcpClient client; private BinaryReader br; private BinaryWriter bw; public MainForm() InitializeComponent(); Random r = new Random
4、(int)DateTime.Now.Ticks); textBoxUserName.Text = user + r.Next(100, 999); listBoxOnlineStatus.HorizontalScrollbar = true; / / 【连接服务器】按钮的Click事件/summary private void buttonConnect_Click(object sender, EventArgs e) buttonConnect.Enabled = false; try /此处为方便演示,实际使用时要将Dns.GetHostName()改为服务器域名 client = ne
5、w TcpClient(192.168.1.43, 51888); AddTalkMessage(连?接成功|); catch失败 buttonConnect.Enabled = true; return; /获取网络流 NetworkStream networkStream = client.GetStream(); /将网络流作为二进制读写对象 br = new BinaryReader(networkStream); bw = new BinaryWriter(networkStream); SendMessage(Login, + textBoxUserName.Text); Thre
6、ad threadReceive = new Thread(new ThreadStart(ReceiveData); threadReceive.IsBackground = true; threadReceive.Start();处理接收的服务器端数据 private void ReceiveData() string receiveString = null; while (isExit = false) /从网络流中读出字符串 /此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = br.ReadString(); if (isExit = fals
7、e) MessageBox.Show(与服务器失去联系 break; string splitString= receiveString.Split(, string command = splitString0.ToLower(); switch (command) case login: /格式:login,用户名 AddOnline(splitString1);logout logout,用户名 RemoveUserName(splitString1);talktalk,用户名,对话信息 /AddTalkMessage(splitString1 + :rn /AddTalkMessage
8、(receiveString.Substring( / splitString0.Length + splitString1.Length+2); AddTalkMessage(string.Format(0说:1, splitString1,receiveString.Substring( splitString0.Length + splitString1.Length + 2); default:什么意思啊: + receiveString); Application.Exit();向服务器端发送信息 private void SendMessage(string message) /将
9、字符串写入网络流,此方法会自动附加字符串长度前缀 bw.Write(message); bw.Flush();发送失败!【发送】按钮的的Click事件 private void buttonSend_Click(object sender, EventArgs e) if (listBoxOnlineStatus.SelectedIndex != -1) /SendMessage(Talk, + listBoxOnlineStatus.SelectedItem + , + textBoxSend.Text+ + textBoxSend.Text); textBoxSend.Clear(); e
10、lse请?先在当前线?中D选?择?一个?对?话者?关闭窗口时触发的事件 private void MainForm_FormClosing(object sender, FormClosingEventArgs e) /未与服务器连接前client为null if (client != null)Logout, isExit = true; br.Close(); bw.Close(); client.Close();在发送信息文本框中按下【Enter】键触发的事件 private void textBoxSend_KeyPress(object sender, KeyPressEventAr
11、gs e) if (e.KeyChar = (char)Keys.Return) /触发buttonSend的Click事件 buttonSend.PerformClick(); private delegate void MessageDelegate(string message); 在richTextBoxTalkInfo中追加聊天信息 private void AddTalkMessage(string message) if (richTextBoxTalkInfo.InvokeRequired) MessageDelegate d = new MessageDelegate(Add
12、TalkMessage); richTextBoxTalkInfo.Invoke(d, new object message ); richTextBoxTalkInfo.AppendText(message + Environment.NewLine); richTextBoxTalkInfo.ScrollToCaret(); private delegate void AddOnlineDelegate(string message);listBoxOnlineStatus中D添加在线的其他客户端信息 private void AddOnline(string userName) if (
13、listBoxOnlineStatus.InvokeRequired) AddOnlineDelegate d = new AddOnlineDelegate(AddOnline); listBoxOnlineStatus.Invoke(d, new object userName ); listBoxOnlineStatus.Items.Add(userName); listBoxOnlineStatus.SelectedIndex = listBoxOnlineStatus.Items.Count - 1; listBoxOnlineStatus.ClearSelected(); priv
14、ate delegate void RemoveUserNameDelegate(string userName);listBoxOnlineStatus中D移除不在线的其它客户端信息 private void RemoveUserName(string userName) RemoveUserNameDelegate d = RemoveUserName; listBoxOnlineStatus.Invoke(d, userName); listBoxOnlineStatus.Items.Remove(userName); private void MainForm_Load(object
15、sender, EventArgs e) (2)服务器模式:using System.Collections.Generic;namespace SyncChatServer保存连接的所有用户 private List userList = new List();使用本机的IP地址 IPAddress localAddress;监听端口 private const int port = 51888; private TcpListener myListener;是否正常退出所有接受线程 bool isNormalExit = false; listBoxStatus.HorizontalScr
16、ollbar = true; IPAddress addrIP = Dns.GetHostAddresses(Dns.GetHostName(); localAddress = addrIP0; buttonStop.Enabled = false;【开始监听】按钮的Click事件 private void buttonStart_Click(object sender, EventArgs e) myListener = new TcpListener(localAddress, port); myListener.Start(); AddItemToListBox(string.Forma
17、t(开始在0:1监听客户连接, localAddress, port); /创建一个线程监听客户端连接请求 Thread myThread = new Thread(ListenClientConnect); myThread.Start(); buttonStart.Enabled = false; buttonStop.Enabled = true;接受客户端连接客户端信息 private void ReceiveData(object userState) User user = (User)userState; TcpClient client = user.client; while
18、 (isNormalExit = false) /从网络流中读出字符串,此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = user.br.ReadString(); if (isNormalExit = false)与0失去联系,已终止接收该用户信息, client.Client.RemoteEndPoint); RemoveUser(user);来自0:, user.client.Client.RemoteEndPoint, receiveString); string splitString = receiveString.Split( switch
19、 (splitString0)Login user.userName = splitString1; SendToAllClient(user, receiveString);LogoutTalk string talkString = receiveString.Substring(splitString0.Length + splitString1.Length + 2);0对1说:2 user.userName, splitString1, talkString); SendToClient(user, talk, + user.userName + + talkString); foreach (User target in userList) if (target.userName = splitString1 & user.userName != splitString1) SendToClient(target, AddItemToListBox(什么意思啊? / 发送message给user指定发给哪个用户message信息内容 private void SendToClient(User user, string message) user.bw.Write(message); user.bw.Flush();向0
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1