提示
总体功能图:
必须先启动server窗口,再启动client窗口,否则报错。
整体框架参考了:https://blog.csdn.net/johnWcheung/article/details/70148959
后续修改了bug、增加了多人聊天、发送图片等功能,美化了界面。
完整代码在链接内。
服务端
界面设计:
功能:
- IP为本机IP(通过命令行自行查看)
- 端口号自定
- 启动服务后,会显示当前在线用户、在线用户数量、用户交流消息
- 在最右边的框内会显示发送的图片
- 断开服务后用户不可再进行任何操作
完整代码:
https://github.com/Susie2000/C/blob/master/IntgerOperats
public partial class FrmServer : Form
{
internal static Hashtable clients = new Hashtable();//clients数组保存当前在线用户的Client对象
private TcpListener listener;//该服务器默认的监听端口号
static int MaxNum = 100;//服务器可以支持的客户端最大连接数
internal static bool ServiceFlag = false;//开始服务的标志
public FrmServer()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
//服务器监听的端口号通过getValidPort()函数获得
private int getValidPort(string port)
{
int lport;
//测试端口号是否有效
try
{
//是否为空
if (port == "")
{
throw new ArgumentException("端口号为空,不能启动服务器");
}
lport = System.Convert.ToInt32(port);
}
catch (Exception e)
{
Console.WriteLine("无效的端口号:" + e.ToString());
this.rtbMessage.AppendText("无效的端口号:" + e.ToString() + "\n");
return -1;
}
return lport;
}
客户端
界面设计:
功能:
- 现在左端输入服务器的IP,端口号,用户名进行登录
- 登陆成功后,可发送消息,图片
- 私聊:先点击用户,勾选私聊(不可选自己),即可私发消息
- 多人聊天:按Ctrl选择多个用户(不包括自己),勾选多人聊天即可
- 可选择发送字体颜色
bug:因为传送图片用的是地址字符串,所以在不同电脑接收时必须事先将图片保存在相同地址处。
完整代码:
https://github.com/Susie2000/C/blob/master/IntgerOperats
public partial class FrmClient : Form
{
TcpClient tcpClient;//与服务器的连接
private NetworkStream Stream;//与服务器交互的流通道
private static string CLOSED = "closed";
private static string CONNECTED = "connected";
private string state = "closed";
private bool stopFlag;
private Color color;//保存当前客户端显示的颜色
//传送文件
static Stream fs = null;
int nameLen = 0;
string name;
long contentLen = 0;
public FrmClient()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
private void FrmClient_Load(object sender, EventArgs e)
{
//IP与端口固定
txtHost.AppendText("192.168.213.1");
txtPort.AppendText("6666");
}
private void btnLogin_Click(object sender, EventArgs e)
{
if (state == CONNECTED)
return;
if (this.username.TextLength == 0)
{
MessageBox.Show(" 请输入你的昵称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
this.username.Focus();//为控件设置焦点
return;
}
try
{
//创建一个客户端套接字,他是Login的一个公共属性
tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Parse(txtHost.Text), Int32.Parse(txtPort.Text));//向指定的IP地址服务器发出连接请求
Stream = tcpClient.GetStream(); //获得与服务器数据交互的流通道 NetworksStream
//启动一个新的线程,执行方法this.ServerResponse(),以便来响应从服务器发回的信息
Thread thread1 = new Thread(new ThreadStart(this.ServerResponse));
thread1.Start();
//向服务器发送CONN请求命令
//此命令的格式与服务器端的定义的格式一致
//命令格式为:命令标志符CONN|发送者的用户名
string cmd = "CONN|" + this.username.Text + "|";
//将字符串转化为字符数组
Byte[] outbytes = System.Text.Encoding.Default.GetBytes(cmd.ToCharArray());
Stream.Write(outbytes, 0, outbytes.Length);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}