我初学dephi 第五天,高分求解(关于Dephi 的ServerSocket) (300分)

  • 主题发起人 主题发起人 e_jie
  • 开始时间 开始时间
E

e_jie

Unregistered / Unconfirmed
GUEST, unregistred user!
我初学dephi 第五天,希望大家多多发言帮忙!
我本来想给500分的,结果发现只能给300分。

在VB中,一个socket Server 程序大致是这样实现的:
1。在指定Port启动监听服务(如:sckServer.listen)
2. 在client端请求时,会触发ConnectionRequest事件。

Private Sub sckServer_ConnectionRequest(ByVal requestID As Long)
'这时,可以这样
sckServer.Accept requestID
'requestID是请求的ID
'也可以这样,(一般用这种方法)
'创建一个socket实例如sck(n),然后 sck(n).accept requestID
End Sub
这样sckServer一直listen,而sck(n)与各自的client Socket单独通信。

而在dephi中,
ServerSocket1.Port:=strtoint(txtport.Text );
ServerSocket1.active:=true;
然后在ClientRead Event :
socket.SendText (strMessage);

我用5个socketClient 程序并发同时发1000个包(总共5000个),全部返回(每个
client收到他发的1000个)
我在任务管理器看到线程在自动创建和销毁。
我本来以为需要创建线程,然后在线程中创建socket,并accept,并通信。但是看来
ServerSocket已把它全部封装了。

请问:
1。可以拒绝client的请求吗?(在VB中,一个Client请求如果不被accept,则连接不会建立
,而dephi的ServerSocket好像是自动accept的,不需要任何代码(真是把我当傻瓜)
2。作这样的SocketServer需要多线程吗(指在线程中建立每一个独立的连接)
3。希望知道关于Dephi socket的更多的东西。


谢谢!

 
请问你的ServerSocket设置的阻塞方式是什么?
是stNonBlocking还是stNonBlocking?如果是前面的一个,serversocket响应OnAccept,OnClientRead,OnClientWrite等
事件;如果是后者那末serversocket将只响应OnGetThread,OnGetSocket,在OnGetSocket中
你确定是否要接受这个客户,在OnGetThread中你需要自己编写一个以TServerClientThread为基类
的子类,在这个子类中你需要处理所有的读和写操作,并将其返回。

如果不懂可以再问。
 
你说,'在这个子类中你需要处理所有的读和写操作,并将其返回。' 返回以后连接建立的吗?

不懂,再请教!
 
ServerType 为stNonBlocking 但是响应了OnGetSocket!

不懂!
 
如果使用的是stNonBlocking你可以试试OnClientConnnect,但我建议你使用stThreadBlocking,
你可以在你自己的TServerClientThread中重写一个ClientExecute函数,如下:


代码:
procedure TMyServerThread.ClientExecute;

var
  Stream : TWinSocketStream;
  Buffer : array[0 .. 9] of Char;
begin
  { make sure connection is active }
  while (not Terminated) and ClientSocket.Connected do
  begin
    try
      Stream := TWinSocketStream.Create(ClientSocket, 60000);
      try
        FillChar(Buffer, 10, 0); { initialize the buffer }
        { give the client 60 seconds to start writing }
        if Stream.WaitForData(60000) then  

        begin
          if Stream.Read(Buffer, 10) = 0 then { if can抰 read in 60 seconds }
            ClientSocket.Close;               { close the connection }
          { now process the request }
          ...
        end
        else
          ClientSocket.Close; { if client doesn抰 start, close }
      finally
        Stream.Free;
      end;
    except
      HandleException;

    end;
  end;
end;
 
你看你上面的代码,连接不是已建立了吗?

可以拒绝连接吗? (而不是在连接后关闭)

请指教!

 
你可以在OnGetSocket事件中判断ClientSocket.RemoteAddress或其它值,如果不喜欢就调用
ClientSocket.Disconnect(Socket);把这个家伙踢出去。就象我下面做得那样。

代码:
procedure TForm1.ServerSocket1GetSocket(Sender: TObject; Socket: Integer;
  var ClientSocket: TServerClientWinSocket);
begin
        ClientSocket:=TServerClientWinSocket.Create(Socket,ServerSocket1.Socket);
        form1.Caption:=ClientSocket.RemoteAddress;
        ClientSocket.Disconnect(Socket);
end;
 
Write an OnClientConnect event handler to take specific action when a client socket completes the socket connection to the server socket. For example, the socket may start reading or writing over the connection in an OnClientConnect event handler.
The order of server socket events leading up to OnClientConnect is as follows:
1 An OnListen event occurs just before the server socket is opened for listening.
2 The server socket receives client requests in a listening queue. The server socket accepts one of those requests, and receives a Windows socket handle for the new socket connection.
3 The server socket generates an OnGetSocket event, passing in the Windows socket handle. If a TServerClientWinSocket object for the server endpoint of the new connection is not created in an OnGetSocket event handler, the server socket creates one. The TServerWinSocket object continues to listen for other clients.
4 An OnAccept event occurs, using the new TServerClientWinSocket object.
5 If ServerType is stThreadBlocking and no thread is available in the cache, an OnGetThread event occurs. If the OnGetThread event handler does not create a thread, the server socket creates a TServerClientThread.
6 If ServerType is stThreadBlocking, an OnThreadStart event occurs as the thread begins execution.
7 The client completes the connection to the TServerClientWinSocket object and an OnClientConnect event occurs.

Note: If ServerType is stThreadBlocking, make sure that all code in an OnClientConnect event handler is thread-safe. Use the GetClientThread method of the Sender parameter to access thread-specific information.
Note: The OnClientConnect event handler for TServerSocket is also set when setting the OnClientConnect event handler of the associated TServerWinSocket.


OnClientConnect是在连接完全建立后触发的
OnGetsocket是在收到请求时触发的(类似vb的ConnectionRequest(ByVal requestID As Long))

 
连接很显然是自动建立的,但是你可以在OnGetSocket是将其踢出。
 
ClientSocket:=TServerClientWinSocket.Create(Socket,ServerSocket1.Socket);
触发了OnClientConnect事件

我的问题是:可以拒绝连接吗? (而不是在连接后关闭)

 
我的问题一开始显然就是:可以不自动建立连接吗?即拒绝client request.
而不是,连接后拒绝接受数据(即立即关闭!)
 
client request的不能拒绝的,除非你预先包过滤,你只能用Disconnect
 
不是拒绝请求,我的意思是收到请求,但是不建立连接。
procedure TForm1.ServerSocket1GetSocket(Sender: TObject; Socket: Integer;
var ClientSocket: TServerClientWinSocket);
begin
ClientSocket:=TServerClientWinSocket.Create(Socket,ServerSocket1.Socket);
form1.Caption:=ClientSocket.RemoteAddress;
ClientSocket.Disconnect(Socket);
end;

procedure TfrmSckServer.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
socket.SendText ('OK!');
end;

我这样做,但是实际上,还是收到了client的请求,并建立了连接,并受到了数据,并返回
给了client
那在OnGetSocket里的disconnect有什么用呢。
 
学了5天就这么高的水平!
 
怎么订阅邮件通知没什么用啊?
只好灌一次水了
 
当你使用stNonBlocking的的时候,由客户端发来的请求不是一个一个发过来的,而是一次就都
发到服务器端,放在一个队列中,在你连接以后这个队列就已经在处理之中了。所以希望你使用
stThreadBlocking,在客户端使用ctBlocking。这样的话,服务器就不会在连接还没有确认前
响应客户机的请求了。
 
'连接还没有确认前'
'响应客户机的请求'

是嘛,我的问题是,连接可以由程序确认吗?(即可以拒绝连接吗?)
难道我的问题问的不清楚。
我想'响应请求'与'建立连接'应该是两个过程吧!
 
我想知道不管是stThreadBlocking 还是 stnonBlocking
怎样确认一个连接(即可以确认,或不确认) ,还是说,无法确认,只能在connect后disconnect!
 
你不能确认连接,连接是自动的,但如果你使用stThreadBlocking你可以不响应非法客户端
的请求。
 
不响应 怎么做!!
 
后退
顶部