我做了服务器端与客户端程序,服务器端接收客户端程序发送过来的数据后查询数据库,然后把查询结果返回给客户端。每次发送的字符不会超过100个。服务器端放在WIN SERVER 2003上。如果客户端不关闭数据能正常接发,第一次关闭客户端后,重启客户端仍然能够正常通信,第二次关闭后,再重启,提示信息两端已经连接,但是就是不能通信,这个时候把服务器端程序重启后工作正常。谁能告诉我解决的办法与原理?每次关闭客户端程序之前我都对连接套接字进行关闭操作。另外需要说明的是:如果服务器端是在单核CPU、OS是XP上,则不会出现上面的问题,如果服务器端装在双核CPU,也会出现上面的问题。
如果可以,则连接被关闭了,检查代码.不行的话,连接没了...重连吧
{
public TcpClient client;
public NetworkStream ns;
public byte[] read;
public byte[] write;
public DataReadWrite(TcpClient client)
{
this.client = client;
ns = client.GetStream();
read = new byte[client.ReceiveBufferSize];
write=new byte[client.SendBufferSize];
}
public void InitReadArray()
{
read=new byte[client.ReceiveBufferSize];
}
public void InitWriteArray()
{
write=new byte[client.SendBufferSize];
}
}class ServerPrag
{ private bool isExit = false;
TcpListener listener;
private ManualResetEvent allDone = new ManualResetEvent(false);
public Thread myThread;
private ListBox listbox;
private Queue queueRevStr = new Queue();
public ServerPrag()
{
myThread = new Thread(new ThreadStart(AcceptConnection));
myThread.Start();
}
private void AcceptConnection()
{
IPAddress[] ip = Dns.GetHostAddresses(Dns.GetHostName());// Dns.GetHostEntry("localhost").AddressList[0];
IPEndPoint ipendPoint = new IPEndPoint(ip[1], int.Parse(ManangeAppConfig.ReadConfig("Port")));
listener = new TcpListener(ipendPoint);
listener.Start();
while (isExit == false)
{
try
{
allDone.Reset();
AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallBack);
listener.BeginAcceptTcpClient(callback, listener);
allDone.WaitOne();
}
catch (Exception e)
{
queueRevStr.Enqueue("网络连接出现异常:"+e.Message);
break;
}
}
}
private void AcceptTcpClientCallBack(IAsyncResult iar)
{
try
{
allDone.Set();
TcpListener mylistener = (TcpListener)iar.AsyncState;
TcpClient client = mylistener.EndAcceptTcpClient(iar);
queueRevStr.Enqueue("已接受连接……");
DataReadWrite datareadwrite = new DataReadWrite(client);
if (datareadwrite.ns.CanRead)
{
datareadwrite.ns.BeginRead(datareadwrite.read, 0, datareadwrite.read.Length, ReadCallBack, datareadwrite);
queueRevStr.Enqueue("开始接收数据……");
}
else
queueRevStr.Enqueue("客户端程序已经关闭");
allDone.WaitOne();
}
catch (Exception e)
{
queueRevStr.Enqueue("网络连接回调出现异常:" + e.Message);
return ;
}
} static string lsReceivedStr="";
private void ReadCallBack(IAsyncResult iar)
{
DataReadWrite datareadwrite = (DataReadWrite)iar.AsyncState;
allDone.Set();
try
{
int recv = 0;
lsReceivedStr = "";
recv = datareadwrite.ns.EndRead(iar);
if (recv > 0)
{
queueRevStr.Enqueue("数据读取完成!");
allDone.Reset();
lsReceivedStr = Encoding.UTF8.GetString(datareadwrite.read, 0, recv);
queueRevStr.Enqueue("开始处理数据……");
queueRevStr.Enqueue(lsReceivedStr);
if (isExit == false)
{
datareadwrite.InitReadArray();
datareadwrite.ns.BeginRead(datareadwrite.read, 0, datareadwrite.read.Length, ReadCallBack, datareadwrite);
}
allDone.WaitOne();
}
else
{
datareadwrite.client.Close();
datareadwrite.ns.Close();
queueRevStr.Enqueue("远程终端关闭!");
}
}
catch (Exception e)
{
getValFromHash(htclientlist, tempTID);
datareadwrite.client.Close();
datareadwrite.ns.Dispose();
datareadwrite.ns.Close();
queueRevStr.Enqueue("远程终端异常,连接关闭!"+e.Message);
}
}
private void SendString(DataReadWrite datareadwrite, string str)
{
try
{
if (datareadwrite.ns!=null&&datareadwrite.client != null && datareadwrite.client.Client.Connected)
{
datareadwrite.write = Encoding.ASCII.GetBytes(str + "\r\n");
datareadwrite.ns.BeginWrite(datareadwrite.write, 0, datareadwrite.write.Length, new AsyncCallback(SendCallBack), datareadwrite);
datareadwrite.ns.Flush();
queueRevStr.Enqueue("开始回复数据……");
}
else
{
//datareadwrite.ns.Close();
//datareadwrite.client.Client.Disconnect(false);
//datareadwrite.client.Close();
queueRevStr.Enqueue("远程终端关闭,无法发送数据");
}
}
catch (Exception e)
{
datareadwrite.ns.Close();
datareadwrite.client.Client.Disconnect(false);
datareadwrite.client.Close();
queueRevStr.Enqueue("远程终端关闭,无法发送数据");
MessageBox.Show(e.Message+e.StackTrace, "SendString:"+e.Source);
}
} private void SendCallBack(IAsyncResult iar)
{
DataReadWrite datareadwrite = (DataReadWrite)iar.AsyncState; try
{
datareadwrite.ns.EndWrite(iar);
//datareadwrite.client.Client.Shutdown(SocketShutdown.Both);
queueRevStr.Enqueue("回复数据成功!");
queueRevStr.Enqueue("============"+DateTime.Now.ToString()+"===============");
}
catch (Exception e)
{
queueRevStr.Enqueue("回复数据回调出现异常!"+e.Message);
}
}
public void getListBox(ListBox lb)
{
listbox=lb;
}
public void insertListBox()
{
if (listbox.Items.Count > 1000)
listbox.Items.Clear();
if (queueRevStr.Count>0)
{
listbox.Items.Add(queueRevStr.Dequeue().ToString());
}
}
}
class DataRead
{
public NetworkStream ns;
public byte[] msg;
public DataRead(NetworkStream ns, int buffersize)
{
this.ns = ns;
msg = new byte[buffersize];
}
}
public delegate void CloseParentWin();
public partial class InfoForm : Form
{
private bool isLive = false;
private TcpClient client;
private NetworkStream ns;
private ManualResetEvent allDone = new ManualResetEvent(false);
private delegate void SetRichTextBoxReceiveCallBack(string str);
private SetRichTextBoxReceiveCallBack setRichTextBoxReceiveCallBack;
eventReadFromT evReadFromT = new eventReadFromT();
//定义两个队列,第一个队列放置从终端收到的数据,第二个队列放置从中心服务器收到的发往终端的数据
private Queue<string> queueFromT=new Queue<string>();
private Queue<string> queueToT = new Queue<string>();
private Queue<string> queueRevStr = new Queue<string>();
private Queue<string> queueRevStrToT=new Queue<string>();
//CommLib CLib = new CommLib();
Security rijndael = new Security();
//定义一个静态变量是进行计时,如果空闲时间达到60S,中断网络连接
private static int FreeTimes=60;
private static int ConnectTryNum = 0;
private static float psfX = 0,psfY=0;
//委托调用该方法:如果发送数据队列中有数据,并且已经连接到服务器,则发送数据,否则先连接服务器再发送数据
private void readFromQueue(object sender,EventArgs e)
{
string lstemp = "";
if (queueFromT.Count > 0)
{
if (client == null || !client.Connected)
{
if (ConnectTryNum <3)
{
ConnectTryNum++;
SetListBox("正在进行第" + ConnectTryNum.ToString() + "次(共尝试连接3次)尝试连接到中心服务器……");
ConnectServer();
}
else
{
timer1.Enabled = false;
timerSend.Enabled = false;
}
}
else
{
lstemp += queueFromT.Dequeue().ToString();
SendData(lstemp);
}
}
} public InfoForm()
{
InitializeComponent();
Application.EnableVisualStyles();
Application.DoEvents();
setRichTextBoxReceiveCallBack = new SetRichTextBoxReceiveCallBack(SetRichTextBoxReceive);
evReadFromT.rtspEvent +=new delegateReadTSerialPort(readFromQueue);
} //通过一个计时器定时把取得的数据放到一个发送队列中
private void timer1_Tick(object sender, EventArgs e)
{
StringBuilder s = new StringBuilder(120);//申明一个StringBuilder对象
int i = GetDateFromEar(s); //从串口读取一个数据
//i = 1;
string temp = s.ToString();//"0,0,123456800,111,37.25,0,cd3f3e0f000104e0";//
if (i > 0)
{
queueFromT.Enqueue(temp);
}
else
{ MessageBox.Show("读入的数据有误:" + temp, "警告");
}
else
{
FreeTimes--;
if (FreeTimes == 0&&client!=null&&client.Client.Connected)
{
client.Close();
client.Client.Close();
}
}
} private void ConnectServer()
{
client = new TcpClient(AddressFamily.InterNetwork);
IPAddress IP = IPAddress.Parse(ManangeAppConfig.ReadConfig("IP"));
AsyncCallback connectCallBack = new AsyncCallback(ConnectCallBack);
allDone.Reset();
client.BeginConnect(IP, int.Parse(ManangeAppConfig.ReadConfig("Port")), connectCallBack, client);
queueRevStr.Enqueue("开始连接服务器……");
allDone.WaitOne();
} private void ConnectCallBack(IAsyncResult iar)
{
allDone.Set();
try
{
client = (TcpClient)iar.AsyncState;
client.EndConnect(iar);
if (client.Connected)
{
queueRevStr.Enqueue("连接服务器成功!");
listBoxStatus.Invoke(setlistboxcallback, string.Format("与服务器{0}连接成功", client.Client.RemoteEndPoint));
ConnectTryNum = 0;
ns = client.GetStream();
DataRead dataRead = new DataRead(ns, client.ReceiveBufferSize);
ns.BeginRead(dataRead.msg, 0, dataRead.msg.Length, ReadCallBack, dataRead);
queueRevStr.Enqueue("开始从中心服务器读取数据……");
}
else
queueRevStr.Enqueue("无法连接到中心服务器!");
}
catch (Exception e)
{
listBoxStatus.Invoke(setlistboxcallback, "ConnectCallBack(连接中心服务器异常):"+e.Message);
return;
}
}
private void ReadCallBack(IAsyncResult iar)
{
try
{
DataRead dataRead = (DataRead)iar.AsyncState;
int recv = dataRead.ns.EndRead(iar);
string strRecvFromServer=Encoding.UTF8.GetString(dataRead.msg, 0, recv);
queueRevStr.Enqueue("读取返回数据:" + strRecvFromServer);
//如果收到回复数据,则在窗口中显示收到的数据,然后关闭连接
if (strRecvFromServer.Trim().Length > 0)
{
richTextBoxRecv.Invoke(setRichTextBoxReceiveCallBack, strRecvFromServer);
if (isLive == false && ns != null)
{
dataRead = new DataRead(ns, client.ReceiveBufferSize);
ns.BeginRead(dataRead.msg, 0, dataRead.msg.Length, ReadCallBack, dataRead);
}
}
client.Client.Disconnect(true);
client.Client.Close();
client.Close();
}
catch (Exception e)
{
client.Client.Disconnect(true);
client.Client.Close();
client.Close();
}
}
private void SendData(string str)
{
try
{
byte[] bytesdata = Encoding.ASCII.GetBytes(str);
ns.BeginWrite(bytesdata, 0, bytesdata.Length, new AsyncCallback(SendCallBack), ns);
ns.Flush();
queueRevStr.Enqueue("向中心服务器发送数据:"+str);
}
catch (Exception e)
{
//listBoxStatus.Items.Add("SendData(发送数据异常):" + e.Message);
}
}
private void SendCallBack(IAsyncResult iar)
{
try
{
if(ns!=null)
ns.EndWrite(iar);
else
listBoxStatus.Invoke(setlistboxcallback, "与中心服务器连接中断,无法发送数据!");
}
catch (Exception e)
{
listBoxStatus.Invoke(setlistboxcallback, "SendCallBack(发送回调异常):" + e.Message);
}
} //从服务器端收到的数据显示在RichTextBox里
private void SetRichTextBoxReceive(string str)
{
richTextBoxRecv.AppendText(str);
}
private void timerSend_Tick(object sender, EventArgs e)
{
evReadFromT.OnrtspEvent(this, e);
} private void InfoForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null && client.Client.Connected)
{
client.Close();
client.Client.Close();
}
} }
public delegate void delegateReadTSerialPort(object sender,EventArgs e);
class eventReadFromT
{
public event delegateReadTSerialPort rtspEvent;
public void OnrtspEvent(object sender,EventArgs e)
{
if (rtspEvent != null)
rtspEvent(sender,e);
}
}
另外你下边这个判断有问题。要判断网络断开这可不行,问题多多
if (datareadwrite.ns.CanRead)
{
datareadwrite.ns.BeginRead(datareadwrite.read, 0, datareadwrite.read.Length, ReadCallBack, datareadwrite);
queueRevStr.Enqueue("开始接收数据……");
}
else
queueRevStr.Enqueue("客户端程序已经关闭");
allDone.WaitOne();