我BS服务器 开启Socket监听开启多线程多个客户端连接之后为什么只能接受到最后一个连接上的 客户端数据
其他数据发哪了?什么情况
有解答的吗?发送连接上的其他客户端都可以
但就是没接受上来我线程不好Socket也是才接触的帮忙解答下(顺便说下 线程池怎么用好些
其实我之前是都可以接受到的
改线程池 又重启IIS 换回多线程 不用线程池 就这样了 不知道什么原因)
其他数据发哪了?什么情况
有解答的吗?发送连接上的其他客户端都可以
但就是没接受上来我线程不好Socket也是才接触的帮忙解答下(顺便说下 线程池怎么用好些
其实我之前是都可以接受到的
改线程池 又重启IIS 换回多线程 不用线程池 就这样了 不知道什么原因)
其他已经连接的客户端信息接受不到
但服务端 可以 发送数据过去
什么原因啊?
我程序 线程的问题 还是客户端?
(我客户端是硬件的gprs也不能保证 那个就没问题
所以查起BUG来 比较纠结)
private static IPAddress ipa = null;//把IP字符串形式转换为IP实例形式
foreach (IPAddress item in Dns.GetHostEntry("").AddressList)
{
if (System.Text.RegularExpressions.Regex.IsMatch(item.ToString(),
Constants.RegularHttp))
{
ipa = item;
break;
}
}//监听端口2020
TcpListener mylistenter = new TcpListener(ipa, Constants.IPPort);
//ThreadPool.SetMinThreads(10, 10);
//ThreadPool.SetMaxThreads(100, 100);
try
{
mylistenter.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mylistenter.Start();
FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
//int a, b;
//等待处理接入连接请求
while (true)
{
Thread.Sleep(100);
mySocket = mylistenter.AcceptSocket();
listSocket.Add(mySocket);
//构造新实例
DoWork.InitDoWork(mySocket);
Thread mythread = new Thread(new ThreadStart(DoWork.ReceiveMethod));
mythread.Start();
/*ThreadPool.QueueUserWorkItem(o =>
{
Thread.Sleep(100);
a = 0; b = 0;
ThreadPool.GetAvailableThreads(out a, out b);
FileConfig.WritetFile(string.Format(Constants.FileClient, a, b,
Thread.CurrentThread.ManagedThreadId, DateTime.Now, mySocket.RemoteEndPoint));
DoWork.ReceiveMethod();
});*/
}
}
catch (Exception ex)
{
FileConfig.WritetFile(Constants.FileException + ex.ToString());
}
finally
{ }
我去吃饭了 一会来啊
private static IPAddress ipa = null;//把IP字符串形式转换为IP实例形式
foreach (IPAddress item in Dns.GetHostEntry("").AddressList)
{
if (System.Text.RegularExpressions.Regex.IsMatch(item.ToString(),
Constants.RegularHttp))
{
ipa = item;
break;
}
}//监听端口2020
TcpListener mylistenter = new TcpListener(ipa, Constants.IPPort);
//ThreadPool.SetMinThreads(10, 10);
//ThreadPool.SetMaxThreads(100, 100);
try
{
mylistenter.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mylistenter.Start();
FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
//int a, b;
//等待处理接入连接请求
while (true)
{
Thread.Sleep(100);
mySocket = mylistenter.AcceptSocket();
listSocket.Add(mySocket);
//构造新实例
DoWork.InitDoWork(mySocket);
Thread mythread = new Thread(new ThreadStart(DoWork.ReceiveMethod));
mythread.Start();
/*ThreadPool.QueueUserWorkItem(o =>
{
Thread.Sleep(100);
a = 0; b = 0;
ThreadPool.GetAvailableThreads(out a, out b);
FileConfig.WritetFile(string.Format(Constants.FileClient, a, b,
Thread.CurrentThread.ManagedThreadId, DateTime.Now, mySocket.RemoteEndPoint));
DoWork.ReceiveMethod();
});*/
}
}
catch (Exception ex)
{
FileConfig.WritetFile(Constants.FileException + ex.ToString());
}
finally
{ }
我去吃饭了 一会来啊
用于连接后 while()里面处理接收到的数据
我原来都是好的 就是换线程池后 不晓得什么情况
现在看来好像变成单线程了 我去
但客户端都是连接上来的
服务端 可以发送数据
Thread mythread = new Thread(new ThreadStart(DoWork.ReceiveMethod));
mythread.Start();
这样是正常的,就改成这样
ThreadPool.QueueUserWorkItem(v1 => DoWork.ReceiveMethod());
再有问题吧 DoWork 内容发上来吧
谢谢
ThreadPool.SetMinThreads(10, 10);
ThreadPool.SetMaxThreads(100, 100);
这个没问题吧
还是不行 像单线程的 只有最后连接的数据可以上传
我把ReceiveMethod的代码 贴出来吧 //接收客户端消息
int length = 0;
byte[] byteData = null;//new byte[1024];
string request = string.Empty;
string DataHeader = string.Empty;
string DataTrunk = string.Empty;
Flag = true;
while (true)
{
Thread.Sleep(100);
length = socket.Available;
if (socket.Connected && length > 16)
{
try
{
byteData = new byte[length];
//将从客户端流读取的数据保存到字符串request中
socket.Receive(byteData);
request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
DataHeader = string.Empty;
DataTrunk = string.Empty;
ReceiveData(request, ref DataHeader, ref DataTrunk);
FileConfig.WritetFile(string.Format(Constants.FileNewData,
DataHeader, DataTrunk, request.Length, request));
}
catch (Exception ex)
{
FileConfig.WritetFile(socket.RemoteEndPoint.ToString() + Constants.FileColseException +
ex.ToString());
/*if (listSocket.Contains(socket))
{
listSocket.Remove(socket);
}
socket.Shutdown(SocketShutdown.Both);
socket.Close();*/
}
finally
{ }
}
}
应该就这些了 我开启的 线程和Socket连接 我还没处理关闭的呢
有问题...唉 在琢磨呢
ThreadPool.SetMaxThreads(100, 100);
这两个不要去动开启 代码
foreach (IPAddress item in Dns.GetHostEntry("").AddressList)
{
if (System.Text.RegularExpressions.Regex.IsMatch(item.ToString(),
Constants.RegularHttp))
{
ipa = item;
break;
}
}//监听端口2020
TcpListener mylistenter = new TcpListener(ipa, Constants.IPPort);
//ThreadPool.SetMinThreads(10, 10);
//ThreadPool.SetMaxThreads(100, 100);
try
{
mylistenter.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mylistenter.Start();
FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
//int a, b;
//等待处理接入连接请求
while (true)
{
mySocket = mylistenter.AcceptSocket();
ThreadPool.QueueUserWorkItem(DoWork.ReceiveMethod, mySocket);
}
}
catch (Exception ex)
{
FileConfig.WritetFile(Constants.FileException + ex.ToString());
}
finally
{ }
ReceiveMethod 代码
private static void ReceiveMethod(object state)
{
Socket socket = (Socket)state;
int length = 0;
byte[] byteData = null;//new byte[1024];
string request = string.Empty;
string DataHeader = string.Empty;
string DataTrunk = string.Empty;
bool Flag = true;
while (true)
{
Thread.Sleep(100);
length = socket.Available;
if (socket.Connected && length > 16)
{
try
{
byteData = new byte[length];
//将从客户端流读取的数据保存到字符串request中
socket.Receive(byteData);
request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
DataHeader = string.Empty;
DataTrunk = string.Empty;
ReceiveData(request, ref DataHeader, ref DataTrunk);
FileConfig.WritetFile(string.Format(Constants.FileNewData,
DataHeader, DataTrunk, request.Length, request));
}
catch (Exception ex)
{
FileConfig.WritetFile(socket.RemoteEndPoint.ToString() + Constants.FileColseException +
ex.ToString());
/*if (listSocket.Contains(socket))
{
listSocket.Remove(socket);
}
socket.Shutdown(SocketShutdown.Both);
socket.Close();*/
}
finally
{ }
}
}
}
学习等待cao老大批判,不是北大青鸟的学生,竟然还用这个阻塞模式啊
request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
一个解析 进库
代码可以贴 可能有点乱
private static void ReceiveData(string data, ref string DataHeader, ref string DataTrunk)
{
//管理器与服务器开始连接
TempIP = socket.RemoteEndPoint.ToString();
//
Mayam.Model.T_USER_DATAH model = new Model.T_USER_DATAH();
model.EquipmentID = EquipmentID;
model.Code = subid;
model.Data = string.Empty;
model.OldData = data;
model.IPAddress = TempIP;
control.Add(model);
if (!RelayState(model))
{
//数据头
DataHeader = data.Substring(0, 16);
//数据枝干
DataTrunk = data.Substring(16, data.Length - 16);
if (DataHeader.ToUpper().StartsWith(Constants.DataStart))
{
temp_sub = string.Empty;
EquipmentID = int.Parse(DataHeader.Substring(12, 4));
//
Mayam.Model.T_USER_Temp temp = temp_control.GetModel(EquipmentID.ToString());
#region 是否为心跳包
if (DataHeader.Substring(4, 2).Equals(Constants.DataStandard))
{
//截取数据包 默认为一包 可包含N组数据解析
foreach (string item in
DataTrunk.Replace(Constants.DataHeaderTail, Constants.DataExcision)
.Split(Constants.DataSeparator))
{
if (item.Length > 4)
{
subid = GetClientID(item.Substring(2, 4));
temp_sub += string.Format(Constants.DataSubsite, subid);
//协议主方法 管理器ID 终端IP端口 子站号
AgreementAnalysis.MainMethod(item, EquipmentID, TempIP, subid);
socket.Send(UTF8Encoding.UTF8.GetBytes(Constants.DataSuccess));
}
}
}
else
{
//心跳包 不予解析
socket.Send(UTF8Encoding.UTF8.GetBytes(Constants.DataXTB));
}
#endregion
lock (lockEdit)
{
temp.IPAddress = TempIP;
temp.Substation = temp_sub.TrimEnd(Constants.DataSeparator);
temp_control.Edit(temp);
}
if (Flag)
{
InitRelay();
Flag = false;
}
}
else
{
//数据头格式不对 不予解析
socket.Send(UTF8Encoding.UTF8.GetBytes(data));
}
}
}
我现在把处理数据的这个方法屏蔽了 再试试看
还有socket.Available要放到变量里
要不在线程里 不晓得什么时候又变为 0 了
也就是
socket.Receive(byteData);
request = System.Text.UTF8Encoding.UTF8.GetString(byteData);
这里 就没进来
貌似还是不行
我端口没重置好
打开的Socket监听 不知道怎么关
我本机server2003里
可以直接关闭WebDev.WebServer40.exe这个进程
开启的端口就关了但服务器是server2008的 找不到关闭的地方...
也总不能老重启服务器吧...
//ThreadPool.SetMaxThreads(100, 100);
其实随意设置它们并不好,因为你不知道客户机器的硬件配置。线程池是托管的,你不用去关心最大数和最小数,不要同时去开启太多的线程,同时保证线程能正常退出就行了
开启的Socket监听...
WF程序的关闭所有就可以了
所以就 重启IIS=。=!
有好方法吗?指导下
别告诉我再进程间 通讯
我现在已经实现了
只是感觉有点不稳定 开启的端口会断开
listSocket.Add(mySocket);
我理解就是listSocket应该是一个socket集合作为连接池的吧?
但是从这几行代码上看到,实际上你的listSocket里面所有的socket都是最后一个客户端连上的socket,Socket是服务端和客户端之间的通讯通道,如果有N个客户端连上了,服务端应该有N个socket实例的,服务端和每个客户端通讯的socket实例是不同的,大概看了下代码,您服务端和客户端的通讯是否仅仅只是最后一次连接的客户端是有效的?
只是用于存储连接上的socket
主要用于发送指令的时候找到对应的socket
对于接受没有具体作用的
应该不是这个问题
但很奇怪之前是好的...
怀疑是不是server2008不熟悉
或IIS7.0不熟悉 导致的
mylistenter.Start();
FileConfig.WritetFile(Constants.FileListenter + mylistenter.LocalEndpoint.ToString());
//int a, b;
//等待处理接入连接请求
while (true)
{
Socket mySocket = mylistenter.AcceptSocket();
ThreadPool.QueueUserWorkItem(DoWork.ReceiveMethod, mySocket);
}这样试试呢?
AcceptSocket();等待连接
开线程 一样是进副本
建议:
服务器端坚决 不能用阻塞模式。(需要用begin开头的函数,坚决制止sleep函数)
线程池不用操心,底层已经做了。
管理好缓冲区
一般都需要添加Session管理逻辑。
现在BS上有这个需求 还望指出
我在看http://www.cnblogs.com/kingmoon/archive/2011/04/29/2032452.html
Socket的异步通信 之前的是同步通信 我才知道=。=!
用起来 怪怪的 上的链接研究了下
没有加上线程池 接受数据也是有些问题
要么是连接接受一次后断
改过代码 不断了 但只接受一次 好像没有持续监听接受的意思...
还望指导下 线程池+Socket异步通信 监听接受
class listener
{
public TcpListener myListener;
public int port = 808;
public MainForm mainform = null;
public bool isabort=false; public void StartListen()
{
try
{
myListener = new TcpListener(port);
myListener.Start();
mainform.MessageShow("服务已启动");
}
catch (Exception e)
{
mainform.MessageShow(e.ToString());
return;
}
bool sdif=ThreadPool.SetMaxThreads(100, 100);//设置线程池线程数量
//int sds, dsd;
//ThreadPool.GetMaxThreads(out sds, out dsd);
while (true)
{
Socket mySocket = null;
if (myListener != null && myListener.Pending())
{
try
{
//接受新连接
mySocket = myListener.AcceptSocket();
}
catch (Exception zxz)
{
mainform.MessageShow(zxz.ToString());
}
}
//Thread.Sleep(5);
if (isabort)
break;
if (mySocket == null)
continue;
mainform.MessageShow("..." + mySocket.RemoteEndPoint.ToString() + "...Connecting......");
ThreadPool.QueueUserWorkItem(ReceiveDataFromSocket, mySocket);
}
} private void ReceiveDataFromSocket(object obj)
{
Socket mySocket = (Socket)obj;
Byte[] bReceive = new Byte[1024 * 1024];
int i = 0;
try
{
//Thread.Sleep(4000);
i = mySocket.Receive(bReceive);
}
catch (Exception zxz)
{
Thread.CurrentThread.Abort();
return;
}
string sBuffer = Encoding.GetEncoding("gb2312").GetString(bReceive, 0, i);
.
........
} }
说下吧 我现在写了
1.仿WF多线程版本 Socket同步通信
——也就是之前的代码
2.线程池版本 Socket同步通信
——改进为线程池 初步验证也可以 但是没用异步的...
3.线程池 Socket异步通信版本
——在研究 =。=!求指点