您的位置:首页 > 其它

局域网之间的通讯实现

2013-12-24 22:08 411 查看
局域网之间通讯有很多种方法,比如可以用数据库存储的方式实现,还可以用udp来实现,这里是用tcp来实现的,用tcp来通讯的话可以说是有点麻烦的,因为要保持各个用户与服务器之间的连接,连接一断便不能通讯了,所以个人觉得这个地方比较麻烦;

要实现Socket通讯的话首先可以把它分成两个项目来区别,一个是服务器项目(Server),一个是客户端项目(Client)。

服务器项目的实现可以大致的分成 部分,1:创建一个总连接点,这个连接点负责与客户端的连接,我们不能把连接和通讯都引用到一个连接上,这样服务器会崩溃的,而每个用户都是独立的,所以我们要利用线程来创建一个新的通讯实例,这个连接和通讯各个用户之间都是互不干扰的了,还有一个要注意的就是跨线程调用控件的话是不行的,所以我们又要利用委托存放要调用的功能在用this.Invoke()的方法来跨线程引用控件,接下来就是具体实现响应通讯了;

客户端相对来说要更容易些,创建一个客户端连接实例,与远程服务器连接起来,然后就是大致的通讯实现功能了。

下面是我个人的实现代码和实现的心得,附加了大致的注释,实现了群聊,私聊等功能。

通讯类(Communication)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Server;

namespace Client
{
public partial class forClient : Form
{
public forClient()
{
InitializeComponent();
}

private delegate void ListDelegate(Communication comm);
private ListDelegate listInfo = null;//用于绑定成员
private delegate void MessageDelegate(Communication comm);
private MessageDelegate MessageInfo = null;//用于添加聊天消息
private delegate void ClearDelegate();
private ClearDelegate ClearInfo = null;//用于清除成员列表
private delegate void EndDelegate(Communication commun);
private EndDelegate EndInfo = null;
Socket client = null;
EndPoint endPoint = null;
private void 开启服务ToolStripMenuItem_Click(object sender, EventArgs e)
{
int port = 0;
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
if (!int.TryParse(txtPort.Text, out port))
port = 8080;
endPoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), port);
client.Connect(endPoint);
rtbMessage.Text = "连接服务器成功!";
Thread t = new Thread(ReceiveInfo);
t.Start(client);
}
public void ClearList() //清除成员列表
{
this.lvInfo.Clear();
}
public void EndClient(Communication commun) //移除成员列表里离线的成员
{
foreach (ListViewItem items in lvInfo.Items)
{
//如果成员列表上有此用户,则移除
if (items.SubItems[0].Text.Equals(commun.Name))
{
items.Remove();
break;
}
}
}
public void ReceiveInfo(object c)//接收服务器的信息
{
byte[] b = new byte[1024];
Socket client = c as Socket;
ClearInfo = new ClearDelegate(ClearList);
while(true)
{
try
{
client.Receive(b);
}
catch (Exception)
{
client.Dispose();
return;
}
Communication comm = DeserializeObject(b) as Communication;
if (comm.Types == 2)//服务器回发过来的信息
{
listInfo = new ListDelegate(BindListView);
this.Invoke(listInfo, comm);
}
else if (comm.Types == 1 || comm.Types == 3)
{
MessageInfo = new MessageDelegate(AddMessage);
this.Invoke(MessageInfo, comm);
}
else //下线执行
{
MessageInfo = new MessageDelegate(AddMessage);
this.Invoke(MessageInfo, comm);
EndInfo = new EndDelegate(EndClient);
this.Invoke(EndInfo,comm);
}
}
}
public void BindListView(Communication comm) //绑定客户端人物信息到ListView控件上
{
if(comm.IsFistLogin)
{
lvInfo.Items.Clear();//第一次添加的时候(判定为true时)清除原有的旧成员
}
ListViewItem items = new ListViewItem(comm.Name);
items.SubItems.Add(comm.Ip);
items.SubItems.Add(comm.Port);
lvInfo.Items.Add(items);
}
public void AddMessage(Communication comm)//添加聊天消息
{
rtbMessage.Text += "\n"+comm.Name + ":" + comm.Message;
}
public object DeserializeObject(byte[] pBytes)//反序列化二进制为对象
{
object newOjb = null;
if (pBytes == null)
return newOjb;
MemoryStream memory = new MemoryStream(pBytes);
memory.Position = 0;
BinaryFormatter formatter = new BinaryFormatter();
newOjb = formatter.Deserialize(memory);
memory.Close();
return newOjb;
}
public byte[] SerializeObject(object pObj)//序列化对象为二进制的数
{
if (pObj == null)
return null;
MemoryStream memory = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memory, pObj);
memory.Position = 0;
byte[] read = new byte[memory.Length];
memory.Read(read, 0, read.Length);
memory.Close();
return read;
}

private void btnSend_Click(object sender, EventArgs e)
{
Communication comm = new Communication() {
Name = Dns.GetHostName(),
Message = txtMessage.Text,
Types = 1
};
if (lvInfo.SelectedItems.Count > 0)//私聊
{
comm.Types = 3;
string ePoint = lvInfo.SelectedItems[0].SubItems[1].Text +":"+ lvInfo.SelectedItems[0].SubItems[2].Text;
comm.ToEndPoint = ePoint;
}
byte[] b = SerializeObject(comm);
client.Send(b);
lvInfo.SelectedItems.Clear();//清除选中的个数
}

private void 退出程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
Communication comm = new Communication()
{
Name = Dns.GetHostName(),
Message = "下线了!",
Types = 4//用户下线类型
};
byte[] b = SerializeObject(comm);
client.Send(b);
client.Dispose();
Application.Exit();
}

private void forClient_Load(object sender, EventArgs e)
{
//127.0.0.1 用于获取本机IP
txtIP.Text = "192.168.1.100";
txtPort.Text = "8080";
}
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: