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

.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务3[聊天室][使用IE浏览本页]

2012-03-28 10:14 1396 查看
本案例使用前面封装的网络服务类编写简易聊天室,采用Tcp和多线程相关技术:





App.config文件:





示范代码<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!--本地服务器名-->
<add key="ServerName" value="127.0.0.1"/>
<!--本地端口-->
<add key="ServerPort" value="6000"/>

<!--远程服务器名-->
<add key="RemoteServerName" value="127.0.0.1"/>
<!--远程服务器端口-->
<add key="RemoteServerPort" value="6000"/>
</appSettings>
</configuration>


窗体内所有代码:





示范代码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 TcpLabCommon;
using System.Net.Sockets;
using System.Net;
using System.Configuration;
using System.Threading;
using System.IO;

namespace TcpLabChat1
{
public partial class FrmChat : Form
{
delegate void UpdateViewHandler(NetPacket packet);
delegate void UpdateViewWithMsgHandler(string msg);
/// <summary>
/// Tcp服务对象[提供发包和收包功能],接收消息和文件使用
/// </summary>
NetPacketService tcpPacketServiceSvr = null;

/// <summary>
/// Tcp服务对象[提供发包和收包功能],发送消息和文件使用
/// </summary>
NetPacketService tcpPacketServiceClient = null;

/// <summary>
/// 客户端Socket[发送消息和文件]
/// </summary>
Socket clientSocket = null;

public string ServerName
{
get
{
return ConfigurationManager.AppSettings["ServerName"];
}
}

public Int32 ServerPort
{
get
{
return Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
}
}

public String RemoteServerName
{
get
{
return ConfigurationManager.AppSettings["RemoteServerName"];
}
}

public Int32 RemoteServerPort
{
get
{
return Convert.ToInt32(ConfigurationManager.AppSettings["RemoteServerPort"]);
}
}

public FrmChat()
{
InitializeComponent();
}

private void FrmChat_Load(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(ReceiveMessage));
thread.IsBackground = true;//设置当前线程为后台线程,以使当主窗体被关闭后自动结束线程
thread.Start();
}

private void ReceiveMessage()
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint endPoint = new IPEndPoint(IPAddress.Parse(ServerName), ServerPort);//创建一个终结点
serverSocket.Bind(endPoint);//绑定终结点
serverSocket.Listen(0);//开始监听

Socket ctSocket = serverSocket.Accept();//接收一个请求
NetworkStream netStream = new NetworkStream(ctSocket);
tcpPacketServiceSvr = new NetPacketTcpService(netStream);

while(true)
{
//在窗口界面所在的线程运行委托指向的方法,避免跨线程访问UI问题
Invoke(new UpdateViewHandler(UpdateView), tcpPacketServiceSvr.ReceivePacket());
}
}

/// <summary>
/// 更新界面
/// </summary>
/// <param name="packet"></param>
private void UpdateView(NetPacket packet)
{
String msglist = txtMsgList.Text;
switch (packet.PacketHead.PType)
{
case PacketType.STRING:
msglist += "\r\n对方说:"+packet.Data.ToString();
break;
case PacketType.BINARY:
NetFile f = tcpPacketServiceSvr.ParseFile((Byte[])packet.Data);
msglist += "\r\n接收了对方发送的文件:"+f.FileName;
FileStream fs = null;
try
{
string fname = Application.StartupPath+"\\"+f.FileName;
fs = new FileStream(fname, FileMode.Create);
fs.Write(f.Content, 0, f.Content.Length);
fs.Flush();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
fs.Close();
}
break;
case PacketType.COMPLEX:
break;
default:
break;
}

txtMsgList.Text = msglist;
}

private void UpdateView(string msg)
{
String msglist = txtMsgList.Text;
msglist += "\r\n"+msg;
txtMsgList.Text = msglist;
}

/// <summary>
/// 发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSendMsg_Click(object sender, EventArgs e)
{
if (txtMsg.Text.Trim().Length == 0)
return;

if (clientSocket == null)
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(IPAddress.Parse(RemoteServerName), RemoteServerPort);
NetworkStream netStream = new NetworkStream(clientSocket);
tcpPacketServiceClient = new NetPacketTcpService(netStream);
}

tcpPacketServiceClient.SendText(txtMsg.Text.Trim());
String msglist = txtMsgList.Text;
msglist += "\r\n我说:" + txtMsg.Text.Trim();
txtMsgList.Text = msglist;
}

/// <summary>
/// 发送文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSendFile_Click(object sender, EventArgs e)
{
OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
{
return;
}

if (clientSocket == null)
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(IPAddress.Parse(RemoteServerName), RemoteServerPort);
NetworkStream netStream = new NetworkStream(clientSocket);
tcpPacketServiceClient = new NetPacketTcpService(netStream);
}

//在新的线程中完成文件发送
Thread thread = new Thread(delegate() //采用C#2.0匿名方法语法
{
tcpPacketServiceClient.SendFile(fd.FileName);

//在窗口界面所在的线程运行委托指向的方法,避免跨线程访问UI问题
Invoke(new UpdateViewWithMsgHandler(UpdateView), "我发送了文件:" + new FileInfo(fd.FileName).Name);
});
thread.IsBackground = true;
thread.Start();

}
}
}


使用方式:请将编译后的debug目录拷贝两份,分别配置不同的端口即可,比如a目录的配置端口为本地6001,远程6002,b目录的配置端口为本地6002,远程6001,这样即可在同一台机器实现通信。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐