客户端不固定,安装多少个就要有多少个,但是关键是,服务端可能定期执行数据到数据库,如何更新到数据库后,客户端可以显示出来?
解决方案 »
- Wpf的布局问题
- c#用Linq语句操作DataGridView
- 通过VPN连接的机子如何取得本机的IP、MAC、主机名等信息?
- 初做项目,用户登录后权限判断问题
- [高分请教]C#读取Excel数据,文件中某些数据竟然读到DataSet中却为空?
- 为什么用vs2003编译可以运行的线程操作到vs2005里就出错了呢?(附图)
- 还有问题要问(WORD文档中某些已知字符串变成红色或者是加下划线)
- 如何使窗体不让用户改变大小?马上结贴
- 在线等,运行在X64下的错误
- 已知圆心坐标和半径如何用wpf计算圆周上N个等分点的坐标
- 【正则表达式难题3】匹配[sum(tab1.col1 where (col2 = '01' or col3 > 0) and col4 <>'02')]规则的校验!
- [WINFORM]调用多线程方法的问题
2)服务器有数据更新时,发个消息给客户端,强迫客户端读数据
另外wcf你也可以试一下,在这个平台下实际上就是建立了一种双向绑定机制,早先我在wpf下实验过,效果很不错,服务器向客户端的推送是以广播的形式,客户端跟服务器连接就在广播列表里注册.
如果你不原意socket或者wcf的话也可以用bs的思路,那就是每到一段时间客户端就主动到服务期里去取记录.
8楼的思路基本正确,但是有一点,LZ说了客户端不定,难道你需要把客户端的IP保存在服务端??不现实。LZ的这种要求来看,Socket必须是短连接,长链接就不合适了。最好的办法就是你说的第一条,客户端每隔多少多少秒进行对服务端的一次轮询,让客户端获得服务端保存的数据。服务端获得数据,比如说StringCollection [] a = new StringCollection[2];
a[0]存储用户名,比如abc001,a[1]存储你需要的数据,当然你需要多个数据的话,a[]可以定义多点。客户端连接上来的时候,将客户端的用户名传输上来,服务端对上传的用户名和a进行匹配,匹配完毕,将对应的数据返回。如果你需要实时性高点,你可以将客户端的轮询时间定义的快点,比如5秒左右。
不过你的结贴率有点低哦····我上次问了个问题,就3个人回答,还没有我想要的答案。。结果2个人10分,1个人20分。。心疼啊
服务端
public partial class Server : Form
{
//clients 哈希列表保存当前在线用户的Client对象
internal static Hashtable clients =new Hashtable(); //该服务器默认的监听端口号
private TcpListener listener;
//服务器可以支持的客户端的最大连接数
static int MAXNUM=100;
//开始服务的标志
internal static bool SocketServiceFlag = false;
private void tsdStart_Click(object sender, EventArgs e)
{
int port = getValidPort("9569");
if (port < 0)
{
return;
}
string ip = this.getIPAddress();
try
{
//IPAddress ipAdd = IPAddress.Parse(ip);
//创建服务器套接字
listener = new TcpListener(IPAddress.Any, port);
//开始监听服务器端口
listener.Start(); this.lbServerState.Text="Socket服务器已经启动,正在监听" + ip + "端口号:9569";
//启动一个新的线程,设置StartSocketListen为true,用一个新建的独立线程执行与客户端确认、连接的操作
SocketServiceFlag = true;
Thread thread = new Thread(new ThreadStart(this.StartSocketListen));
thread.Start();
this.tsConsole.DropDownItems["tsdStart"].Visible = false;
this.tsConsole.DropDownItems["tsdStop"].Visible = true;
}
catch(Exception)
{
}
}
/// <summary>
/// 在新的线程中的操作,它主要用于当接收到一个新的客户请求时,确认与客户端的连接,并且立刻启动一个新的线程来处理和该客户端的信息交互.
/// </summary>
private void StartSocketListen()
{
while (SocketServiceFlag)
{
try
{
//第一个监听线程已经把客户尝试连接的信息实例后挂起在队列中
//这里的挂起队列起到一个缓冲作用,你不能获取它的大小,但你能判断实例被挂起 if (listener.Pending())
{
//根据挂起队列中的实例信息实例一个Socket
Socket socket = listener.AcceptSocket();
if (clients.Count >= MAXNUM)
{
socket.Close();
}
else
{
//启动一个新的线程,调用Client类
Client client = new Client(this, socket);
Thread clientService = new Thread(new ThreadStart(client.ServiceClient));
clientService.Start();
}
}
}
catch
{
}
}
}
}
客户类登陆之后再给它发消息哦.
再做一个与客户端通信的类
public class Client
{
...
private Socket currentSocket = null;
...
/// <summary>
/// 实现向客户端发送命令请求的功能
/// </summary>
/// <param name="client">目标客户端信息类Client实例</param>
/// <param name="msg">要发送的数据</param>
public void SendToClient(Client client, string msg)
{
System.Byte[] message = System.Text.Encoding.GetEncoding("GB2312").GetBytes(msg.ToCharArray());
try
{
client.CurrentSocket.Send(message, message.Length, 0);
Thread.Sleep(200);
}
catch (Exception)
{
client.loseDispose(false);
client = null;
}
}
public void ServiceClient()
{
//用于存取接收到的客户端命令的字符串数组
string[] tokens = null;
//定义一个1024字节的缓存数组,一次循环存入缓存的长度
byte[] buff = new byte[1048576];
//用循环来不断与客户端进行交互,直到客户端发出"EXIT"命令,将keepConnect设置为false或SocketServiceFlag被设置为false(服务停止),关闭连接并中止当前线程
while (keepConnect && Server.SocketServiceFlag)
{
//清空
tokens = null;
try
{
//判断当前连接socket是否为空或可读取的数据量不足时,等待0.3秒后进入下一循环
if (currentSocket == null || currentSocket.Available < 1)
{
Thread.Sleep(300);
//跳出循环进入下一循环
continue;
}
//记录放入缓存的长度
int len = currentSocket.Receive(buff);
//这里写接收代码
.....
}}}
}
2、客户端定时刷新数据。
3、使用XMPP技术
运用wcf实现你想要的功能:
http://www.cnblogs.com/jillzhang/archive/2008/02/24/1079339.html