TCP编写的C-C通讯
服务端代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace C_C
{
public partial class Server : Form
{
private List<User> userList = new List<User>();
IPAddress localAddress;
private const int port = 8888;
private TcpListener myListener;
bool isExit = false;
public Server()
{
InitializeComponent();
}
private void Server_Load(object sender, EventArgs e)
{
textBoxIPAddress.Text = "127.0.0.1";
textBoxPort.Text = "8888";
localAddress = IPAddress.Parse("127.0.0.1");
myListener = new TcpListener(localAddress, port);
myListener.Start();
AddToRichTextBox(string.Format("开始在{0}:8888监听客户连接请求!",localAddress) + "\r\n");
Thread myThread = new Thread(ListenClientConnect);
myThread.Start();
ChangelabelCount("个用户成功连接.");
}
private void ListenClientConnect()
{
TcpClient newClient = null;
while (true)
{
ListenClientDelegate d = new ListenClientDelegate(ListenClient);
IAsyncResult result = d.BeginInvoke(out newClient, null, null);
while (result.IsCompleted == false)
{
if (isExit)
{
break;
}
Thread.Sleep(250);
}
d.EndInvoke(out newClient, result);
if (newClient != null)
{
User user = new User(newClient);
Thread threadReceive = new Thread(ReceiveData);
threadReceive.Start(user);
userList.Add(user);
AddToRichTextBox(string.Format("[{0}]已登录!", newClient.Client.RemoteEndPoint) + "\r\n");
ChangelabelCount("个用户成功连接.");
}
else
{
break;
}
}
}
private void ReceiveData(object userState)
{
User user = (User)userState;
TcpClient client = user.client;
while (isExit == false)
{
string receiveString = null;
ReceiveMessageDelegate d = new ReceiveMessageDelegate(ReceiveMessage);
IAsyncResult result = d.BeginInvoke(user, out receiveString, null, null);
while (result.IsCompleted == false)
{
if (isExit)
{
break;
}
Thread.Sleep(250);
}
d.EndInvoke(out receiveString, result);
if (receiveString == null)
{
if (isExit == false)
{
AddToRichTextBox(string.Format("与[{0}]失去联系,已终止接收该用户信息",client.Client.RemoteEndPoint) + "\r\n");
AsyncSendToAllClient(user,"Logout," + user.userName);
listBoxSelectClient.Items.Remove(user.userName);
RemoveUser(user);
}
break;
}
string[] splitString = receiveString.Split(',');
switch (splitString[0])
{
case "Login":
user.userName = splitString[1];
AsyncSendToAllClient(user, receiveString + "," + user.client.Client.RemoteEndPoint);
AddTolistBoxClient(user.userName);
break;
case "Talk":
string talkString = receiveString.Substring(splitString[0].Length + 1);
AddToRichTextBox(string.Format("来自[{0}]的消息:{1}", user.userName, talkString));
break;
default:
AddToRichTextBox("什么意思:" + receiveString);
break;
}
}
}
private void AsyncSendToClient(User user, string message)
{
SendToClientDelegate d = new SendToClientDelegate(SendToClient);
IAsyncResult result = d.BeginInvoke(user, message, null, null);
while (result.IsCompleted == false)
{
if (isExit)
{
break;
}
}
d.EndInvoke(result);
}
private delegate void SendToClientDelegate(User user, string message);
private void SendToClient(User user, string message)
{
try
{
user.bwriter.Write(message);
user.bwriter.Flush();
AddToRichTextBox(string.Format("向[{0}]发送:{1}", user.userName,message) + "\r\n");
}
catch
{
AddToRichTextBox(string.Format("向[{0}]发送信息失败", user.userName) + "\r\n");
}
}
private void AsyncSendToAllClient(User user, string message)
{
string command = message.Split(',')[0].ToLower();
if (command == "login")
{
for (int i = 0; i < userList.Count; i++)
{
AsyncSendToClient(userList[i], message);
if (userList[i].userName != user.userName)
{
AsyncSendToClient(user, "login," + userList[i].userName + "," + userList[i].client.Client.RemoteEndPoint);
}
}
}
else if (command == "logout")
{
for (int i = 0; i < userList.Count; i++)
{
if (userList[i].userName != user.userName)
{
AsyncSendToClient(userList[i], message);
}
}
}
}
private void RemoveUser(User user)
{
userList.Remove(user);
user.Close();
ChangelabelCount("个用户成功连接.");
}
private delegate void ReceiveMessageDelegate(User user, out string receiveMessage);
private void ReceiveMessage(User user, out string receiveMessage)
{
try
{
receiveMessage = user.breader.ReadString();
}
catch (Exception ex)
{
AddToRichTextBox(ex.Message + "\r\n");
receiveMessage = null;
}
}
private delegate void ListenClientDelegate(out TcpClient client);
private void ListenClient(out TcpClient newClient)
{
try
{
newClient = myListener.AcceptTcpClient();
}
catch
{
newClient = null;
}
}
private delegate void labelCountChangedDelegate(string str);
private void ChangelabelCount(string str)
{
if (labelClientCount.InvokeRequired)
{
labelCountChangedDelegate del = ChangelabelCount;
labelClientCount.Invoke(del, str);
}
else
{
labelClientCount.Text = userList.Count + str;
}
}
private delegate void AddToRichTextBoxDelegate(string str);
private void AddToRichTextBox(string str)
{
if (richTextBoxShowMessage.InvokeRequired)
{
AddToRichTextBoxDelegate del = AddToRichTextBox;
richTextBoxShowMessage.Invoke(del, str);
}
else
{
richTextBoxShowMessage.Text += str;
}
}
private void Server_FormClosing(object sender, FormClosingEventArgs e)
{
if (myListener != null)
{
isExit = true;
for (int i = userList.Count - 1; i >= 0; i--)
{
RemoveUser(userList[i]);
}
myListener.Stop();
}
}
private delegate void AddTolistBoxClientDelegate(string str);
private void AddTolistBoxClient(string str)
{
if (listBoxSelectClient.InvokeRequired)
{
AddTolistBoxClientDelegate del = AddTolistBoxClient;
listBoxSelectClient.Invoke(del, str);
}
else
{
listBoxSelectClient.Items.Add(str);
listBoxSelectClient.SelectedIndex = listBoxSelectClient.Items.Count - 1;
listBoxSelectClient.ClearSelected();
}
}
}
}
客户端代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net;
namespace C_C_Client
{
public partial class Client : Form
{
private bool isExit = false;
private TcpClient myclient;
private BinaryReader breader;
private BinaryWriter bwriter;
private List<UserClient> userlist = new List<UserClient>();
private UdpClient receiveClient;
public Client()
{
InitializeComponent();
listBoxClient.HorizontalScrollbar = true;
}
void ConnectToServer()
{
myclient = new TcpClient();
IAsyncResult result = myclient.BeginConnect(IPAddress.Parse("127.0.0.1"),8888, null, null);
while (result.IsCompleted == false)
{
Thread.Sleep(100);
AddToShowMessage(".");
}
try
{
myclient.EndConnect(result);
AddToShowMessage("连接成功!\r\n");
NetworkStream networkStream = myclient.GetStream();
breader = new BinaryReader(networkStream);
bwriter = new BinaryWriter(networkStream);
AsyncSendMessage("Login," + textBoxUserName.Text);
Thread threadReceive = new Thread(new ThreadStart(ReceiveData));
threadReceive.IsBackground = true;
threadReceive.Start();
receiveClient = new UdpClient((IPEndPoint)myclient.Client.LocalEndPoint);
Thread threadUdpReceive = new Thread(new ThreadStart(ReceiveUdpData));
threadUdpReceive.IsBackground = true;
threadUdpReceive.Start();
}
catch (Exception ex)
{
AddToShowMessage("连接失败:" + ex.Message + "\r\n");
buttonConnect.Enabled = true;
textBoxUserName.Enabled = true;
}
}
private void buttonConnect_Click(object sender, EventArgs e)
{
buttonConnect.Enabled = false;
textBoxUserName.Enabled = false;
AddToShowMessage("开始连接!\n");
ConnectToServer();
}
private void ReceiveData()
{
string receiveString = null;
while (isExit == false)
{
ReceiveMessageDelegate d = new ReceiveMessageDelegate(ReceiveMessage);
IAsyncResult result = d.BeginInvoke(out receiveString, null, null);
while(result.IsCompleted == false)
{
if(isExit)
{
break;
}
Thread.Sleep(250);
}
d.EndInvoke(out receiveString, result);
if(receiveString == null)
{
if(isExit == false)
{
MessageBox.Show("与服务器失去联系.");
listBoxClient.Items.Clear();
buttonConnect.Enabled = true;
textBoxUserName.Enabled = true;
richTextBoxReceiveMessage.Clear();
}
break;
}
string[] splitString = receiveString.Split(',');
string command = splitString[0].ToLower();
switch(command)
{
case "login":
AddListBoxClient(splitString[1]);
UserClient user = new UserClient(splitString[1], splitString[2]);
userlist.Add(user);
break;
case "logout":
RemoveUserName(splitString[1]);
for (int i = 0; i < userlist.Count; i++ )
{
if(userlist[i].UserName.Equals(splitString[1]))
{
userlist.RemoveAt(i);
AddToShowMessage(string.Format("{0}已退出!", splitString[1]) + "\r\n");
break;
}
}
break;
}
}
}
delegate void ReceiveMessageDelegate(out string receiveMessage);
private void ReceiveMessage(out string receiveMessage)
{
receiveMessage = null;
try
{
receiveMessage = breader.ReadString();
}
catch (Exception ex)
{
AddToShowMessage(ex.Message + "\r\n");
}
}
private struct SendMessageStates
{
public SendMessageDelegate d;
public IAsyncResult result;
}
private void AsyncSendMessage(string message)
{
SendMessageDelegate d = new SendMessageDelegate(SendMessage);
IAsyncResult result = d.BeginInvoke(message, null, null);
while(result.IsCompleted == false)
{
if(isExit)
{
return;
}
Thread.Sleep(50);
SendMessageStates states = new SendMessageStates();
states.d = d;
states.result = result;
Thread t = new Thread(FinishAsyncSendMessage);
t.IsBackground = true;
t.Start(states);
}
}
private void FinishAsyncSendMessage(object obj)
{
SendMessageStates states = (SendMessageStates)obj;
states.d.EndInvoke(states.result);
}
delegate void SendMessageDelegate(string message);
private void SendMessage(string message)
{
try
{
bwriter.Write(message);
bwriter.Flush();
}
catch
{
AddToShowMessage("发送失败!\r\n");
}
}
private delegate void AddListBoxClientDelegate(string message);
private void AddListBoxClient(string message)
{
if(listBoxClient.InvokeRequired)
{
AddListBoxClientDelegate d = new AddListBoxClientDelegate(AddListBoxClient);
listBoxClient.Invoke(d, message);
}
else
{
listBoxClient.Items.Add(message);
listBoxClient.SelectedIndex = listBoxClient.Items.Count - 1;
listBoxClient.ClearSelected();
}
}
private delegate void RemoveUserNameDelegate(string userName);
private void RemoveUserName(string userName)
{
if(listBoxClient.InvokeRequired)
{
RemoveUserNameDelegate d = new RemoveUserNameDelegate(RemoveUserName);
listBoxClient.Invoke(d, userName);
}
else
{
listBoxClient.Items.Remove(userName);
listBoxClient.SelectedIndex = listBoxClient.Items.Count - 1;
listBoxClient.ClearSelected();
}
}
private delegate void AddToShowMessageDelegate(string message);
private void AddToShowMessage(string message)
{
if (richTextBoxReceiveMessage.InvokeRequired)
{
AddToShowMessageDelegate d = new AddToShowMessageDelegate(AddToShowMessage);
richTextBoxReceiveMessage.Invoke(d, message);
}
else
{
richTextBoxReceiveMessage.AppendText(message);
}
}
private void buttonSendToServer_Click(object sender, EventArgs e)
{
AsyncSendMessage("Talk," + richTextBoxSendMessage.Text + "\r\n");
richTextBoxSendMessage.Clear();
}
private void Client_FormClosing(object sender, FormClosingEventArgs e)
{
if(myclient != null)
{
isExit = true;
if(myclient.Client.Connected)
{
breader.Close();
bwriter.Close();
}
myclient.Close();
}
}
private void buttonSendToClient_Click(object sender, EventArgs e)
{
if (listBoxClient.SelectedItem == null)
{
MessageBox.Show("请选择一个用户!");
}
else if (listBoxClient.SelectedItem.ToString().Equals(textBoxUserName.Text))
{
MessageBox.Show("请重新选择用户!");
}
else
{
foreach(UserClient user in userlist)
{
if(user.UserName.Equals(listBoxClient.SelectedItem))
{
SendData(user);
break;
}
}
}
}
private void SendData(UserClient user)
{
UdpClient sendUdpClient = receiveClient;
IPEndPoint iEndPoint = new IPEndPoint(IPAddress.Parse(user.localEndPoint.Split(':')[0]),int.Parse(user.localEndPoint.Split(':')[1]));
string sendMessage = richTextBoxSendMessage.Text;
byte[] bytes = Encoding.UTF8.GetBytes(sendMessage);
try
{
IAsyncResult result = sendUdpClient.BeginSend(bytes, bytes.Length, iEndPoint, SendCallback, sendUdpClient);
string message = string.Format("我对[{0}]说:{1}", user.UserName, sendMessage);
AddToShowMessage(message + "\r\n");
richTextBoxSendMessage.Clear();
richTextBoxSendMessage.Focus();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,"发送失败");
}
}
public void SendCallback(IAsyncResult result)
{
UdpClient udpClient = (UdpClient)result.AsyncState;
udpClient.EndSend(result);
}
private void ReceiveUdpData()
{
IAsyncResult result = receiveClient.BeginReceive(ReceiveUdpClientCallback,receiveClient);
result.AsyncWaitHandle.WaitOne();
}
void ReceiveUdpClientCallback(IAsyncResult result)
{
try
{
UdpClient client = (UdpClient)result.AsyncState;
IPEndPoint remote = null;
Byte[] receiveBytes = client.EndReceive(result, ref remote);
string receiveMessage = Encoding.UTF8.GetString(receiveBytes, 0, receiveBytes.Length);
foreach(UserClient user in userlist)
{
if(user.localEndPoint.Equals(remote.ToString()))
{
AddToShowMessage(string.Format("[{0}]:", user.UserName) + receiveMessage + "\r\n");
}
}
ReceiveUdpData();
}
catch(Exception ex)
{
AddToShowMessage("错误信息:" + ex.Message);
}
}
}
}