使用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(); } } } }
先运行服务器端后运行客户端