昨天编了个局域网QQ,能够实现基本的聊天功能了,现把思路及方法分享。指高手指点建议
用了三个窗体:一个登录窗体,登录成功后关闭,启动《显示在线好友》的窗体,
点击在线好友,启动聊天窗体。我把QQ号码放在一台SQL服务器上的,登录窗体就是验证QQ号码及密码正确否
在线好友窗体,Load事件:
一,向数据库中写进自己的IP地址,侦听端口及在线状态
二,从数据库中读出所有在线的QQ用户名称及其IP地址,侦听端口,添加进QQ在线好友列表
三,启动自己的侦听服务,以便别的QQ在线好友可以连接自己,实现和自己聊天
四,双击QQ好友列表中的任一个在线用户,连接此QQ的IP地址,侦听端口,打开聊天窗体开始聊天
界面见下参考(比较简陋):
用到的技术Socket及多线程,如在线好友窗体启动侦听端口另开线程
Thread threadListen = new Thread(ServerListen);
threadListen.Start();
private void ServerListen()
{
while (true) //侦听客户连接
{
TcpClient tcpClient = serverListener.AcceptTcpClient();
if (tcpClient.Connected)
{ //如果有客户建立连接,又再打开线程开启聊天窗体聊天
Thread threadClient = new Thread(ClientConnect);
threadClient.Start(tcpClient);
}
}
}
//如果有客户建立连接,又再打开线程开启聊天窗体聊天
private void ClientConnect(object sender)
{
Application.Run(new FrmChat(sender,this.Text,null));
}
//聊天窗体发送聊天内容
private void button1_Click(object sender, EventArgs e)
{
//发送聊天内容
NetworkStream netStream = tcpClient.GetStream();
byte[] bBuffer = Encoding.GetEncoding("gb2312").GetBytes(sLocalUserName + " " + DateTime.Now.ToString() + "\n " + richTextBox2.Text + "\n");
netStream.Write(bBuffer, 0, bBuffer.Length);
richTextBox1.AppendText(sLocalUserName + " " + DateTime.Now.ToString() + "\n " + richTextBox2.Text + "\n");
richTextBox2.Text = "";
richTextBox2.Focus();
richTextBox2.SelectAll();
}
要注意的是聊天窗体接收聊天内容也要另开线程,否则用户界面会卡住,以下是聊天窗体的Load事件
private void FrmChat_Load(object sender, EventArgs e)
{
IPEndPoint remoteEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint;
if (sRemoteUserName != null)
{
NetworkStream netStream = tcpClient.GetStream();
byte[] bBuffer = Encoding.GetEncoding("gb2312").GetBytes(sLocalUserName + "和您建立了连接,准备与您会话,请知悉。谢谢!\n\n");
netStream.Write(bBuffer, 0, bBuffer.Length);
}
Thread threadRecv = new Thread(RecvData); //再开线程,用于接收聊天内容,代码见下,继续贴出
threadRecv.Start();
richTextBox2.Focus();
richTextBox2.SelectAll();
}
//接收聊天内容
private void RecvData()
{
while (true)
{
try
{
if (tcpClient.Connected)
{
NetworkStream netStream = tcpClient.GetStream();
int iRecvLength = netStream.Read(bBuffer, 0, 1024);
if (iRecvLength > 0)
{
sRecvStr = Encoding.GetEncoding("gb2312").GetString(bBuffer, 0, iRecvLength);
if (sRecvStr.StartsWith("Exit Quit Close Offline"))
{
sRecvStr = sRemoteUserName + "和您断开了连接,无法与您会话,请知悉。谢谢!\n";
richTextBox2.ReadOnly = true;
button1.Enabled = false;
}
richTextBox1.AppendText(sRecvStr);
if (sRecvStr.Substring(sRecvStr.Length - 24, 22).StartsWith("和您建立了连接,准备与您会话,请知悉。谢谢!"))
{
sRemoteUserName = sRecvStr.Substring(0, sRecvStr.Length - 24);
this.Text = "和" + sRemoteUserName + "会话中";
}
}
}
}
catch
{
}
}
}