我的serversocket多线程老是重复接受数据,客户端发送数据后,服务器端线程接受后,老是重复接受感觉客户端一直在发送一样,但是如果服务器端改为非阻塞的就只有一次,我问了他们的工程师,说是本来也只发了一次,郁闷惨了,我把代码贴出来,大家看看怎么回事
procedure TserverThread.ClientExecute;
var
ReceiveBuffer:Array[0..300] Of byte;//16进制
InputStream:TWinSocketStream;
str,strData:string;
len,i:integer;
sStream:TWinSocketStream;
sBuffer:array[0..3071] of byte;
Begin
//获取和操作命令,直到连接断开或者线程终止
while not Terminated and ClientSocket.Connected do
Begin
Try
strdata:='';
len:=ClientSocket.ReceiveLength;
sStream:= TWinSocketStream.Create(ClientSocket,3000);
try //填充SBuffer数组
FillChar(sBuffer,sizeof(sbuffer),0);
//延迟时间60秒
If sStream.WaitForData(3000) then
Begin
If sStream.Read(sBuffer,sizeof(sbuffer))=0 then
begin
FillChar(sBuffer,sizeof(sbuffer),0);
sBuffer[0]:=$C0;
sBuffer[1]:=$00;
sBuffer[2]:=$08;
sBuffer[3]:=$21;
ClientSocket.Close;
end
else
if len>0 then
begin
for i:=0 to len-1 do
begin
str:=inttohex(sBuffer[i],2);
strdata:=strdata+str+' ';
case i of
0:memo1.lines.Add('包的检测码:'+str);
2:memo1.lines.Add('包的大小:'+str);
3:memo1.Lines.Add('功能码:'+str);
end;
end;
memo1.lines.Add(strdata);
FillChar(sBuffer,sizeof(sbuffer),0);
sBuffer[0]:=$C0;
sBuffer[1]:=$00;
sBuffer[2]:=$08;
sBuffer[3]:=$21;
ClientSocket.SendBuf(ReceiveBuffer,8);
clientsocket.Close;
end;
end
else ClientSocket.Close;
except
HandleException;
end;
Finally
sStream.Free;
end;
end;
End;
procedure TserverThread.ClientExecute;
var
ReceiveBuffer:Array[0..300] Of byte;//16进制
InputStream:TWinSocketStream;
str,strData:string;
len,i:integer;
sStream:TWinSocketStream;
sBuffer:array[0..3071] of byte;
Begin
//获取和操作命令,直到连接断开或者线程终止
while not Terminated and ClientSocket.Connected do
Begin
Try
strdata:='';
len:=ClientSocket.ReceiveLength;
sStream:= TWinSocketStream.Create(ClientSocket,3000);
try //填充SBuffer数组
FillChar(sBuffer,sizeof(sbuffer),0);
//延迟时间60秒
If sStream.WaitForData(3000) then
Begin
If sStream.Read(sBuffer,sizeof(sbuffer))=0 then
begin
FillChar(sBuffer,sizeof(sbuffer),0);
sBuffer[0]:=$C0;
sBuffer[1]:=$00;
sBuffer[2]:=$08;
sBuffer[3]:=$21;
ClientSocket.Close;
end
else
if len>0 then
begin
for i:=0 to len-1 do
begin
str:=inttohex(sBuffer[i],2);
strdata:=strdata+str+' ';
case i of
0:memo1.lines.Add('包的检测码:'+str);
2:memo1.lines.Add('包的大小:'+str);
3:memo1.Lines.Add('功能码:'+str);
end;
end;
memo1.lines.Add(strdata);
FillChar(sBuffer,sizeof(sbuffer),0);
sBuffer[0]:=$C0;
sBuffer[1]:=$00;
sBuffer[2]:=$08;
sBuffer[3]:=$21;
ClientSocket.SendBuf(ReceiveBuffer,8);
clientsocket.Close;
end;
end
else ClientSocket.Close;
except
HandleException;
end;
Finally
sStream.Free;
end;
end;
End;
解决方案 »
- idpop3接收正文不正确问题 (delphi7+indy9)急,在线等待,不够加分
- 通讯方向案征集,高手请进
- 一個GroupBox里面有10個CheckBox.怎麼樣得到所有的CheckBox的Caption?:
- 在创建一个进程时,系统会不会出现一个消息
- 请各位大师指点:网络上两个数据库数据传送问题(在线等待)
- listview 问题
- 怎样在一个事件中触发另一个事件
- 公司的网能上,但是OICQ上不去请各位支招
- 怎样把数据库的表备份出来?急!
- delphi2007 如何安装indy9.0
- Delphi版 关于QQ输入控件无法Spy到句柄的实现方案可行性研究
- 请教,Listbox问题............................................
后再加个
break;
会不会好一点?
procedure TForm1.TcpServer1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread :=TserverThread.Create(false,ClientSocket,listbox1); end;
会不停的被触发,生成线程,但是客户端根本就没有发送任何数据
begin
FillChar(sBuffer,sizeof(sbuffer),0);
sBuffer[0]:=$C0;
sBuffer[1]:=$00;
sBuffer[2]:=$08;
sBuffer[3]:=$21;
ClientSocket.Close;
end
else
if len>0 then //影响到这条判断语句
//因为如果连接关闭后,实际接收长度为0,但是你的Len值没有被赋值为0,所以会反复执行判断条件中的语句
begin应改为
Len:=sStream.Read(sBuffer,sizeof(sbuffer));
if Len=0 then //如果本次读取的数据长度为0,则说明连接关闭了
begin
FillChar(sBuffer,sizeof(sbuffer),0);
sBuffer[0]:=$C0;
sBuffer[1]:=$00;
sBuffer[2]:=$08;
sBuffer[3]:=$21;
ClientSocket.Close;
end
else
if len>0 then
begin
每个连接建立一个线程通讯,没什么问题啊,当连接存在的时候线程不需要Terminate
private void SocketStart()
{
try
{
IPAddress localAddr = IPAddress.Parse(serverIP);
GpsListener = new TcpListener(localAddr, serverPort); // TcpListener Listener = new TcpListener(port);
GpsListener.Start(); // Start listening for client requests.
ConnectOK = 0;
myForm.showInfo("***** 监听软件已经启动..... *****\r\n\r\n");
while (true) {
try
{
GpsSocket = GpsListener.AcceptSocket();
GPSServiceThread = new Thread(new ThreadStart(ServiceClient));
GPSServiceThread.Start();
Thread.Sleep(5);
}
catch
{
}
private void ServiceClient()
{
try
{
//string Myip = "";
string MyPort = "";
string path = Application.StartupPath + @"\GpsSocketInfo.txt";
Socket ThisTempSocket = GpsSocket;
bool keepalive = true;
while (true)
{
Byte[] GpsBuffer = new Byte[1024];
int bufLen = 0;// MessageBox.Show(myForm.Test());
try
{
bufLen = ThisTempSocket.Available;//获取已经从网络接收且可供读取的数据量。
ThisTempSocket.Receive(GpsBuffer, 0, bufLen, SocketFlags.None);//将数据放在buffer里
if (bufLen == 0)
continue;
}
catch
{
return;
} int cmd = 0x83;
int cmdws = 0x4D;
if (Convert.ToInt32(GpsBuffer[21]) == cmd)
{
int year = Convert.ToInt32(GpsBuffer[28]);
if ((year == 0))//如果接受到数据是0000则continue
{
myForm.showInfo("\r\n" + "开始接受信息!" + "\r\n");
continue;
} ConvertBufferCmdToStrToSend(GpsBuffer);
continue; } if (Convert.ToInt32(GpsBuffer[21]) == cmdws)
{
setConnectOK(ThisTempSocket, GpsBuffer);
Sendmsg(GpsBuffer);
continue;
} string cmdstr = System.Text.Encoding.ASCII.GetString(GpsBuffer);
if (cmdstr.IndexOf("policy-file") > 0)
{
string s = "<?xml version=\"1.0\"?><cross-domain-policy><site-control permitted-cross-domain-policies=\"all\"/><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>\0";
Byte[] b = System.Text.Encoding.Default.GetBytes(s);
ThisTempSocket.Send(b);
continue;
}
cmdstr = cmdstr.Substring(0, 2); if (cmdstr.Equals("CC"))//客户端的机子发送请求
{
CCresponsion(ThisTempSocket);
continue;
}
Thread.Sleep(5);
}
ThisTempSocket.Close();
}
catch (Exception ex)
{
myForm.showInfo("\r\n" + ex.Message.ToString() + "\r\n");
} }
While (Not Terminated)And FOwner.Active Do
begin
nTickCount := GetTickCount;
If FOwner.FSockStream.WaitForData(FOwner.ReadTimeout) Then // 如果有数据到来
If Not Terminated Then
Repeat
Begin
BytesDone:= FOwner.FSockStream.Read(FReadBuf, 65536);
// 可能错误
If BytesDone = 0 Then
begin
if (GetTickCount - nTickCount)<FOwner.ReadTimeout then
begin
FOwner.Close;
FOwner.FWriteThread.udSuspend;
//重连
FOwner.FWorkThread.FReConnectEvent.SetEvent;
//休眠自己
Suspend;
end;
end
把线程去掉,循环2次,for i=0 to 1 do
begin
通讯过程
end;
调试下通讯过程。就知道对方到底发了几次