高分200,请问:如何得clientSocket发送包超时?谢谢! (200分)

  • 主题发起人 主题发起人 hcai
  • 开始时间 开始时间
H

hcai

Unregistered / Unconfirmed
GUEST, unregistred user!
如何得clientSocket发送包超时?
 
用select来判断,下面的我封装了的函数
int RecvTimeOut(int fd, unsigned int sec)
//判断Socket是否超时,返回0则表示超时
//参数fd为socket连接描述符;参数sec为超时限制值,单位为秒
{
fd_set fs;
struct timeval timeout;
int n;

FD_ZERO(&fs);
FD_SET((unsigned int)fd,&fs);
timeout.tv_sec = sec;
timeout.tv_usec = 0;
n=select(fd+1,&fs,NULL,NULL,&timeout);
return n;
}

//客户端发送代码(非阻塞通信)
void __fastcall TClientForm::Button2Click(TObject *Sender)
{
char CmdBuf[255];
strcpy(CmdBuf, "shutdown");
CliSock->Socket->SendBuf(CmdBuf,sizeof(CmdBuf));
//假设以5秒为超时限制值
if (RecvTimeOut(CliSock->Socket->SocketHandle, 5)==0)
ShowMessage("socket读超时!");
}

//服务器端代码(非阻塞通信,OnClientRead事件)
void __fastcall TServerForm::SvrSockClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
//假设延迟10秒才响应客户端,此时客户端就会提示超时;而如果延迟时间少于
//客户端的超时设置,客户端就不会报超时错误
Sleep(10);
Socket->SendBuf("执行成功",10);
}
 
to:sachow
谢谢您的答复!请问有没有delphi的呢?c++我可忙啦,若有请发表出来吧,谢谢!
 
在error里面判断errorcode
超时的errorcode你查以下我忘了
 
//判断超时的函数,此函数加在客户端程序中,注意要引用WinSock单元
function RecvTimeOut(fd: Cardinal; sec: Word):Integer;
var
fs: TFDSet;
timeout: TTimeVal;
n: Integer;
begin
FD_ZERO(fs);
FD_SET(fd, fs);
timeout.tv_sec := sec;
timeout.tv_usec := 0;
n := Select(fd+1, @fs, nil, nil, @timeout);
Result := n;
end;

//客户端发送代码
procedure TForm1.Button2Click(Sender: TObject);
var
Buf: array [0..255] of Char;
begin
Buf := 'shutdown';
ClientSocket1.Socket.SendBuf(Buf, SizeOf(Buf));
if (RecvTimeOut(ClientSocket1.Socket.SocketHandle, 5)=0) then
begin
ShowMessage('发送超时!');
ClientSocket1.Close;
end;
end;

//服务器端接收代码
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
Buf: array [0..255] of Char;
begin
//延迟一定时间
Sleep(StrToInt(Edit1.Text));
if (Socket.ReceiveBuf(Buf, SizeOf(Buf))>=SizeOf(Buf)) then
Memo1.Lines.Add(Buf);
Buf := '执行成功';
Socket.SendBuf(Buf, SizeOf(Buf));
end;
 
TO sachow:
不行啊,我必须等到TimeOut到才说超时,但其实是正常发送的。下面是我测试的程序段:
请回复,谢谢。

unit Unit1;

interface

uses
Windows, Messages, SysUtils,winsock, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ScktComp;

type
TForm1 = class(TForm)
Button1: TButton;
ClientSocket1: TClientSocket;
ServerSocket1: TServerSocket;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
function RecvTimeOut(fd: Cardinal; sec: Word):Integer;
implementation

{$R *.DFM}
function RecvTimeOut(fd: Cardinal; sec: Word):Integer;
var
fs: TFDSet;
timeout: TTimeVal;
n: Integer;
begin

FD_ZERO(fs);
FD_SET(fd, fs);
timeout.tv_sec := sec;
timeout.tv_usec := 0;
n := Select(fd+1, @fs, nil, nil, @timeout);
Result := n;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//clientsocket1.Host:='liu';
// clientsocket1.Active:=true;
clientsocket1.Socket.SendText('eryteyte');

if (RecvTimeOut(ClientSocket1.Socket.SocketHandle, 10)=0) then
begin
ShowMessage('发送超时!');
ClientSocket1.Close;
end;

end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
label1.Caption:=clientsocket1.Socket.RemoteAddress;

end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
label2.Caption:=Socket.ReceiveText;
end;

end.
 
以前好象有贴子讨论过,你找找看。
 
客户端代码没有错。
是不是服务器那边延迟太长了?只要服务器那边的延迟短于客户端的超时设置,就不会报
超时的。
如果需要的话,我把完整的程序发给你。
 
to sachow:
多谢你的指点,我很想看看您的程序是怎样写的,请把程序发到:hello_cai@163.com
谢谢
 
to sachow:
多谢你的指点,我很想看看您的程序是怎样写的,请把程序发到:hello_cai@163.com
谢谢!
 
接受答案了.
 
后退
顶部