serersocket多线程重复接收数据,全天在线,急,急!!!

photo2000 2009-10-29 12:03:54
加精
我的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;
...全文
1066 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
arjian79 2010-04-09
  • 打赏
  • 举报
回复
可以 增加一個包的編號位,
接收到的包編號都加入到一個列表中,
當接收到新的包,先判斷這個包號在列表中是否已經存在,
如果存在則丟棄;
chrile 2010-03-04
  • 打赏
  • 举报
回复
这几天正搞这些东西,路过学习一下~~~
sanguomi 2009-12-18
  • 打赏
  • 举报
回复
先用抓包工具检查确定他只发了一个包给你还是多个包
然后再检查代码
dd_zhouqian 2009-12-18
  • 打赏
  • 举报
回复

把线程去掉,循环2次,for i=0 to 1 do
begin
通讯过程
end;
调试下通讯过程。就知道对方到底发了几次
wmz110 2009-12-15
  • 打赏
  • 举报
回复
UP
luoyanqing119 2009-12-15
  • 打赏
  • 举报
回复
ClientSocket的lock和unlock虽然很老土,但是很适用的
ruanjian2110 2009-12-08
  • 打赏
  • 举报
回复
学习一下,期待牛人解决。。
无条件为你 2009-11-07
  • 打赏
  • 举报
回复
发送前:ClientSocket.Lock;

发送后:ClientSocket.Unlock;

你自己试一下。
hou0120 2009-11-06
  • 打赏
  • 举报
回复
我测试了,缓冲区接受数据后是自动清空了
zaa123321 2009-11-06
  • 打赏
  • 举报
回复
顶你一下
huangjacky 2009-11-06
  • 打赏
  • 举报
回复
断了你这里是判断不出来的,需要这样


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
llwlz 2009-11-06
  • 打赏
  • 举报
回复
C#的,刚刚完成的,自己看吧
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");
}



}
photo2000 2009-11-05
  • 打赏
  • 举报
回复
现在是当客户端链接后,就生成了一个线程,只要客户端或者服务端不关闭这个soket那么以后一直用这个socket来通讯,我不知道Terminated 什么时候才算结束呢,我的意思是每个线程结束后socket不关闭,不知道咋个整哦
huoxudong125 2009-11-05
  • 打赏
  • 举报
回复
Delphi语言?
imho888 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 photo2000 的回复:]
现在是当客户端链接后,就生成了一个线程,只要客户端或者服务端不关闭这个soket那么以后一直用这个socket来通讯,我不知道Terminated 什么时候才算结束呢,我的意思是每个线程结束后socket不关闭,不知道咋个整哦
[/Quote]

每个连接建立一个线程通讯,没什么问题啊,当连接存在的时候线程不需要Terminate
ailonchang80 2009-10-30
  • 打赏
  • 举报
回复
研究vcl,要么就用api开发
wooden954 2009-10-30
  • 打赏
  • 举报
回复
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 //影响到这条判断语句
//因为如果连接关闭后,实际接收长度为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
。。。
haitao 2009-10-29
  • 打赏
  • 举报
回复
ClientSocket.Close;
后再加个
break;
会不会好一点?
photo2000 2009-10-29
  • 打赏
  • 举报
回复
没人回复吗?着急啊
photo2000 2009-10-29
  • 打赏
  • 举报
回复
我测试了,缓冲区接受数据后是自动清空了,但是
procedure TForm1.TcpServer1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread :=TserverThread.Create(false,ClientSocket,listbox1);

end;
会不停的被触发,生成线程,但是客户端根本就没有发送任何数据

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧