您的位置:首页 > 理论基础 > 计算机网络

利用TCP协议通过Socket编写的网络聊天工具3-服务器端设计

2012-05-14 16:53 597 查看
服务器端的设计因为包含界面,所以启动一个新的线程监听端口,然后每次接受一个Socket以后启动一个新的连接Socket的线程。

整个项目的源代码,稍后给出下载连接。

整个项目源码下载地址:http://download.csdn.net/detail/weixingstudio/4301232

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 UtilityClass;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Threading;
using System.Collections.Specialized;

namespace ChatPlatform
{
public partial class ServerMain : Form
{
IPAddress serverIPAddress;
TcpListener serverListener;
private ServerConfig serverConfig;
private string _serverIP="10.108.13.27";
private int _serverPort = 8888;
private int userCount = 0;
private Hashtable onlineUserHashtable;

Thread serverListenThread;

private delegate void setSystemLogDelegate(string s);
private delegate void setOnlineUserDelegate(string s);

public ServerMain()
{
InitializeComponent();
serverConfig = new ServerConfig(_serverIP,_serverPort);
onlineUserHashtable = new Hashtable();
this.systemlog.ScrollToCaret();
this.button_stop.Enabled = false;
}

private void serverConfigButton_Click(object sender, EventArgs e)
{
int flag = 0;
ServerConfigurationForm configForm = new ServerConfigurationForm(serverConfig);
configForm.ShowDialog();
if (ServerConfigurationForm.Result)
{
MessageBox.Show("修改配置成功!");
}
}

private void button_start_Click(object sender, EventArgs e)
{
if (serverListenThread!=null)
{
// 服务已经开启了
MessageBox.Show("服务已经开启!");
}
else
{
// 开启一个新线程,监听用户连接请求
onlineUserHashtable.Clear(); //  清理在线用户列表
//this.systemlog.Clear();
serverListenThread = new Thread(new ThreadStart(PortListenFunc));
serverListenThread.IsBackground = true;
serverListenThread.Start();
this.button_stop.Enabled = true;
this.button_start.Enabled = false;
}
}

/// <summary>
/// 在一个线程中监听端口连接请求
/// </summary>
/// <param name="obj"></param>
private void PortListenFunc()
{
//
try
{
serverIPAddress = IPAddress.Parse(serverConfig.ServerIP);
serverListener = new TcpListener(serverIPAddress, serverConfig.ServerPort);
serverListener.Start();// 开始监听
RefreshSystemlog("listen port " + serverConfig.ServerPort + " started!."+DateTime.Now);
RefreshSystemlog("server IP:" + serverConfig.ServerIP);
RefreshSystemlog("server port:" + serverConfig.ServerPort);
//开始循环监听端口,接收用户连接
while (true)
{
byte[] receiveBuffer = new byte[serverConfig.MaxBuffer];
Socket newClient = serverListener.AcceptSocket();
if (onlineUserHashtable.Count<serverConfig.MaxAllowedOnlineUser)
{
//Socket newClient = serverListener.AcceptTcpClient();
newClient.Receive(receiveBuffer);
string userName = Command.DecodeCommand(receiveBuffer);
// 验证用户名的有效性
if (onlineUserHashtable.Count != 0 && onlineUserHashtable.ContainsKey(userName))
{
newClient.Send(Command.EncodeCommand(Command.RedundantUserName));
}
else
{
// 用户名有效
onlineUserHashtable.Add(userName, newClient);
newClient.Send(Command.EncodeCommand(Command.ConnectConfirm));
RefreshSystemlog("用户:" + userName + "登录系统" + DateTime.Now);

Thread clientThread = new Thread(new ParameterizedThreadStart(clientFunc));
clientThread.IsBackground = true;
clientThread.Start(userName);

Thread.Sleep(300);
// 通知所有在线用户,有人上线了
foreach (DictionaryEntry de in onlineUserHashtable)
{
string name = de.Key as string;
Socket socket = de.Value as Socket;
//if (!name.Equals(userName))
if (true)
{
// 发送命令
byte[] cmd_byte = Command.EncodeCommand(Command.SomeoneConnected);
socket.Send(cmd_byte);
// 发送用户名
cmd_byte = Command.EncodeCommand(userName);
socket.Send(cmd_byte);
}
}

// 更新在线用户列表
FlashOnlineUser();
}
}
else
{
// 超出了允许的最大连接数
newClient.Receive(receiveBuffer);
string userName = Command.DecodeCommand(receiveBuffer);
newClient.Send(Command.EncodeCommand(Command.ExceedMaxAllowedNumber));
}
}
}
catch (System.Exception ex)
{
// 监听端口出错,关闭服务
RefreshSystemlog("监听端口出错" + DateTime.Now);
RefreshSystemlog("服务关闭!");
RefreshSystemlog(ex.Message);
if (serverListener!=null)
{
serverListener.Stop();
serverListener = null;
}
}
}

/// <summary>
/// 处理每一个连接的客户端的事务
/// </summary>
/// <param name="obj"></param>
private void clientFunc(object obj)
{
string userName = obj as string;
// 获取与客户端通信的套接字
Socket clientSocket = onlineUserHashtable[obj] as Socket;
while (true)
{
if (clientSocket.Connected)
{
try
{
byte[] cmdBuffer = new byte[serverConfig.MaxBuffer];
clientSocket.Receive(cmdBuffer);
// 获取传送过来的命令
string cmd_from_client = Command.DecodeCommand(cmdBuffer);
switch (cmd_from_client)
{
// 请求离开
case Command.DisConnect:
{
onlineUserHashtable.Remove(obj);
RefreshSystemlog("用户:" + userName + "离开系统!" + DateTime.Now);
FlashOnlineUser();
// 给所有用户发消息,某人离开
foreach (DictionaryEntry de in onlineUserHashtable)
{
Socket s = de.Value as Socket;
byte[] cmd = Command.EncodeCommand(Command.SomeoneLeave);
// 发送命令
s.Send(cmd);
Thread.Sleep(50);
cmd = Command.EncodeCommand(userName);
// 发送用户名
s.Send(cmd);
}
Thread.CurrentThread.Abort();
break;
}

// 用户请求在线用户列表
case Command.RequestOnlineUser:
{
byte[] cmd = new byte[serverConfig.MaxBuffer];
string[] user = new string[onlineUserHashtable.Count];
int i = 0;
foreach (DictionaryEntry de in onlineUserHashtable)
{
user[i] = de.Key as string;
i++;
}
// 发送命令
clientSocket.Send(Command.EncodeCommand(Command.SendOnlinUserList));
cmd = Command.SerializeOnlineUser(user);
// 发送在线用户列表
clientSocket.Send(cmd);
break;
}

// 请求对所有用户广播消息
case Command.BroadcastAll:
{
byte[] cmd = new byte[serverConfig.MaxBuffer];
clientSocket.Receive(cmd);
Thread.Sleep(50);
foreach (DictionaryEntry de in onlineUserHashtable)
{
Socket socket = de.Value as Socket;
string name = de.Key as string;
if (!name.Equals(userName))
{
//向所有用户广播消息
socket.Send(Command.EncodeCommand(Command.BroadcastAll));
Thread.Sleep(20);
// 发送广播消息的用户名
socket.Send(Command.EncodeCommand(userName));
Thread.Sleep(20);
//  发送要广播的消息
socket.Send(cmd);
}
}
break;
}

// 请求对某个对象发送数据
case Command.SendMessage2One:
{
// 接收对象名
byte[] cmd = new byte[serverConfig.MaxBuffer];
clientSocket.Receive(cmd);
string name_private = Command.DecodeCommand(cmd);
Thread.Sleep(50);
// 接收数据
byte[] data = new byte[serverConfig.MaxBuffer];
clientSocket.Receive(data);
Thread.Sleep(50);
// 发送数据到目标对象
Socket socket = onlineUserHashtable[name_private] as Socket;
// 发送命令
socket.Send(Command.EncodeCommand(Command.SendMessage2One));
Thread.Sleep(50);
// 发送用户名
socket.Send(Command.EncodeCommand(userName));
Thread.Sleep(50);
socket.Send(data);

break;
}
// 对某个用户抖动
case Command.VibrateOne:
{
byte[] cmd = new byte[serverConfig.MaxBuffer];
clientSocket.Receive(cmd);
string name_private = Command.DecodeCommand(cmd);
Socket socket = onlineUserHashtable[name_private] as Socket;
// 发送抖动命令
socket.Send(Command.EncodeCommand(Command.VibrateOne));
Thread.Sleep(20);
// 发送用户名
socket.Send(Command.EncodeCommand(userName));
break;
}

// 对所有人闪屏
case Command.VibrateAll:
{
//  发送命令
foreach (DictionaryEntry de in onlineUserHashtable)
{
Socket socket = de.Value as Socket;
string name = de.Key as string;
if (!name.Equals(userName))
{
socket.Send(Command.EncodeCommand(Command.VibrateAll));
Thread.Sleep(20);
socket.Send(Command.EncodeCommand(userName));
}
}
break;
}
default:
{
break;
}
}
}
catch (System.Exception ex)
{
// 某个客户端连接发生异常
onlineUserHashtable.Remove(obj);
// 向所有连接发送消息
foreach (DictionaryEntry de in onlineUserHashtable)
{
Socket s = de.Value as Socket;
byte[] cmd = Command.EncodeCommand(Command.SomeoneLeaveUnexpected);
s.Send(cmd);
cmd = Command.EncodeCommand(userName);
s.Send(cmd);
}
Thread.CurrentThread.Abort();
}
}
else
{
// 没有连接则终止线程
Thread.CurrentThread.Abort();
}
}
}

/// <summary>
/// 线程安全的更新在线用户列表
/// </summary>
private void FlashOnlineUser()
{
Action clearOnlineList = delegate() { this.onlineuserlistbox.Items.Clear(); };
this.onlineuserlistbox.Invoke(clearOnlineList);
foreach (DictionaryEntry de in onlineUserHashtable)
{
string name = de.Key as string;
if (this.onlineuserlistbox.InvokeRequired)
{
setOnlineUserDelegate call = delegate(string s) { this.onlineuserlistbox.Items.Add(s); };
this.onlineuserlistbox.Invoke(call,name);
}
else
{
this.onlineuserlistbox.Items.Add(name);
}
}
}

/// <summary>
/// 线程安全的添加系统日志信息
/// </summary>
/// <param name="log"></param>
private void RefreshSystemlog(string log)
{
if (this.systemlog.InvokeRequired)
{
setSystemLogDelegate call = delegate(string s) { this.systemlog.Text += s + "\n"; };
this.systemlog.Invoke(call,log);
}
else
{
this.systemlog.Text += log + "\n";
}
//this.systemlog.Select(this.systemlog.Text.Length, 0);
//this.systemlog.ScrollToCaret();
}

private void button_stop_Click(object sender, EventArgs e)
{
if (serverListener!=null)
{
serverListener.Stop();
RefreshSystemlog("listen port "+serverConfig.ServerPort+" stopped!"+DateTime.Now);
serverListenThread.Abort();
if (onlineUserHashtable.Count!=0)
{
// 清理所有的连接
foreach (DictionaryEntry de in onlineUserHashtable)
{
Socket s = de.Value as Socket;
byte[] cmd = Command.EncodeCommand(Command.ServerShutdown);
s.Send(cmd);
//Thread.Sleep(50);
// 关闭和客户端的连接
s.Close();
}
onlineUserHashtable.Clear(); // 清除用户列表
}
RefreshSystemlog("清理连接用户完毕!" + DateTime.Now);
serverListener = null;
serverListenThread = null;
this.button_stop.Enabled = false;
this.button_start.Enabled = true;
}
else
{
RefreshSystemlog("端口监听已经结束!" + DateTime.Now);
}
}

/// <summary>
/// 用户点击关闭按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void stopService(object sender, FormClosingEventArgs e)
{
//this.Owner.Close();
//if (serverListener!=null)
//{
//    serverListener.Stop();
//    serverListener = null;
//    RefreshSystemlog("service stopped!");
//    serverListenThread.Abort();
//    serverListenThread.Join();
//    serverListenThread = null;
//}
}

private void systemlog_TextChanged(object sender, EventArgs e)
{
this.systemlog.SelectionStart = this.systemlog.TextLength;
this.systemlog.ScrollToCaret();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息