当连接是non-blocking时,连接的另一端企图读或写时读和写事件将把这个信息通知你的socket.读和写操作事件Non-blocking sockets想通过连接读或写时,它会产生一个读和写操作事件通知你的socket.在客户端sockets,你可以在OnRead或OnWrite事件句柄中对这些事件做出反应.在服务器端Scokets,可以在OnClientRead或OnClientWrite事件句柄中对这些事件做出反应.与socket连接相关联的windows socket object在事件句柄的读或写中被当作一个参数.Windows socket object提供一个方法号(number of methods)以允许你通过连接读或写.通过socket连接读,使用ReceiveBuf或ReceiveText方法.在使用ReceiveBuf方法前,使用Receivelength方法去确定在连接的另一端socket准备发送的字节数(number of bytes).通过socket连接写,使用SendBuf,SendStream,或SendText方法.如果你通过socket发送信息后不在需要socket连接,你可以使用SendStreamThenDrop方法. SendStreamThenDrop在写完所有的信息后将关闭Socket连接,它能够从stream读信息.如果你使用SendStream或SendStreamThenDrop方法,不要释放Stream object, socket在连接结束后会自动释放这个Stream.注意:SendStreamThenDrop将关闭一个独立的客户连接服务,而不是监听连接.B.Blocking connections当你使用的连接是Blocking时,你的Socket必须通过连接发起读或写操作,胜过被动的等待从socket连接发来的通知. 当你的连接末端的读和写操作发生改变时使用Blocking socket.对于客户端sockets,设置ClientType属性为ctBlocking 以便构成一个blocing connection.根据你的客户端应用想完成什么,你可能想建立一个执行线程去完成读或写操作,以便你的应用能够继续执行其他的线程,当它在等待通过连接读或写操作的完成.对于服务器sockets,设置ServerType属性为stThreadBlocking以便构成一个blocking connection.因为blocking connections在等待通过连接读或写信息完成时挂起了其他代码的执行,服务器socket控件通常产生一个新的执行线程给每一个客户连接,当ServerType设置为stThreadBlocking时.许多使用Blocking连接的应用都写使用线程(using threads.甚至如果你不使用线程,你可能也想使用(using) TWinSocketStream去读和写.1)using threads当使用一个blocking connection进行读或写操作时,客户sockets不会自动产生一个新线程.如果你的客户应用程序没有什么事做,直到读或写信息完成,那么这正是你想要的.如果你的应用包括了一个用户界面,它还需要响应用户的操作,那么,你可能想产生一个独立的线程去读写.当服务器sockets形成一个blocking连接时,他们常常产生独立的线程给每一个客户连接,所以没有客户需要等待直到其他客户完成通过连接读或写操作.在默认情况下,服务器sockets使用TServerClientThread对象去实现为每个连接执行不同的线程.TServerClientThread对象模拟发生在non-blocking连接中的OnClientRead和OnClientWrite事件.可是,这些事件发生在监听socket上时,不是本地线程(thread-local).如果客户请求频繁,你将想建立你自己的TServerClientThread子类去提供一个安全线程(Thread-Safe)去完成读和写操作. 当写客户线程或写服务器线程时,你能够使用TwinSocketStream去做实际的读写操作.A)写客户端线程为客户端连接写一个线程,定义一个新线程对象,使用新线程对象对话框.你的新线程对象Execute方法的句柄的通过线程连接进行读写操作的细节,可以建立一个TWinSocketStream对象,然后使用它来读或写.使用你自己的线程,在OnConnect事件句柄中建立它.关于建立和运行线程的更多信息,请看Executing thread objects.例子:这个例子显示一个应用的客户线程在连接确定后向服务器发出写请求.void __fastcall TMyClientThread::Execute(){while (!Terminated && ClientSocket1->Active)// make sure connection is active{try{TWinSocketStream *pStream = new TWinSocketStream(ClientSocket1.Socket,60000);try{char buffer[10];GetNextRequest(buffer);// GetNextRequest must be a thread-safe method// write a request to the serverpStream->Write(buffer,strlen(buffer) + 1);// continue the communication (eg read a response)}__finally{delete pStream;}}catch (Exception &E){if (!E.ClassNameIs("EAbort"))Synchronize(HandleThreadException());// you must write HandleThreadException}}}B)写服务器线程服务器连接线程由TServerClientThread派生.因为这个,不能使用新线程对象对话框.替代的,手动声明你的线程如下:class PACKAGE TMyServerThread :public ScktComp::TServerClientThread{publicvoid __fastcall ClientExecute(void);}注意你将用重载ClientExcute方法替代Execute方法.执行ClientExecute方法必须为客户端连接写一个同样的Execute方法线程.然而,当你从控件栏上放一个客户socket控件到你的应用上时来替代这个方法时.监听服务socket同意一个连接时,服务客户线程必须使用TServerClientWinSocket对象来建立.这可以利用共公共的CientSocket属性.另外,你能够使用HandleException这个protected性的方法,胜过你自己写你的thread-safe例外操作.警告:Server sockets会缓存他们使用到的线程.确信ClientExecute方法执行一些必要的初始化操作,以便它们在最后执行时不致于产生不利的结果.当你使用你的线程时,在OnGetThread事件句柄中建立它.当建立线程,设置CreateSuspended参数为false.例子:这个例子显示一个为一个应用服务的线程,这个应用是在连接确定后由客户端来的读请求.void __fastcall TMyServerThread::ClientExecute(){while (!Terminated && ClientSocket->Connected)// make sure connection is active{try{TWinSocketStream *pStream = new TWinSocketStream(ClientSocket,60000);try{char buffer[10];memset(buffer, 0, sizeof(buffer));if (pStream->WaitForData(60000))// give the client 60 seconds to start writing{if (pStream->Read(buffer, sizeof(buffer) == 0)ClientSocket->Close();// if can't read in 60 seconds, close the connection// now process the request}elseClientSocket->Close();}__finally{delete pStream;}}catch (...){HandleException();}}}C.使用TwinSocketStream当为一个blocking连接实现一个线程时,你必须确定在连接的另一端的socket是准备写还是读.Blocking连接不会通知socket当它准备好写或读操作的时候.想看看连接是否准备好,使用TWinSocketStream对象.TWinSocketStream提供一个方法去帮助调整读或写操作时间的选择.调用WaitForData方法去等待,直到socket另一端的准备好写操作.当读写操作使用TWinSocketStream时,如果读或写操作在指定的时间期限内未能完成,Stream将发生超时.这个超时被当作一个结果,socket应用不会暂停,而是不断的通过一个dropped connection试图读或写.注意:你不能在non-blocking连接中使用TWinSocketStream
当连接是non-blocking时,连接的另一端企图读或写时读和写事件将把这个信息通知你的socket.读和写操作事件Non-blocking sockets想通过连接读或写时,它会产生一个读和写操作事件通知你的socket.在客户端sockets,你可以在OnRead或OnWrite事件句柄中对这些事件做出反应.在服务器端Scokets,可以在OnClientRead或OnClientWrite事件句柄中对这些事件做出反应.与socket连接相关联的windows socket object在事件句柄的读或写中被当作一个参数.Windows socket object提供一个方法号(number of methods)以允许你通过连接读或写.通过socket连接读,使用ReceiveBuf或ReceiveText方法.在使用ReceiveBuf方法前,使用Receivelength方法去确定在连接的另一端socket准备发送的字节数(number of bytes).通过socket连接写,使用SendBuf,SendStream,或SendText方法.如果你通过socket发送信息后不在需要socket连接,你可以使用SendStreamThenDrop方法. SendStreamThenDrop在写完所有的信息后将关闭Socket连接,它能够从stream读信息.如果你使用SendStream或SendStreamThenDrop方法,不要释放Stream object, socket在连接结束后会自动释放这个Stream.注意:SendStreamThenDrop将关闭一个独立的客户连接服务,而不是监听连接.B.Blocking connections当你使用的连接是Blocking时,你的Socket必须通过连接发起读或写操作,胜过被动的等待从socket连接发来的通知. 当你的连接末端的读和写操作发生改变时使用Blocking socket.对于客户端sockets,设置ClientType属性为ctBlocking 以便构成一个blocing connection.根据你的客户端应用想完成什么,你可能想建立一个执行线程去完成读或写操作,以便你的应用能够继续执行其他的线程,当它在等待通过连接读或写操作的完成.对于服务器sockets,设置ServerType属性为stThreadBlocking以便构成一个blocking connection.因为blocking connections在等待通过连接读或写信息完成时挂起了其他代码的执行,服务器socket控件通常产生一个新的执行线程给每一个客户连接,当ServerType设置为stThreadBlocking时.许多使用Blocking连接的应用都写使用线程(using threads.甚至如果你不使用线程,你可能也想使用(using) TWinSocketStream去读和写.1)using threads当使用一个blocking connection进行读或写操作时,客户sockets不会自动产生一个新线程.如果你的客户应用程序没有什么事做,直到读或写信息完成,那么这正是你想要的.如果你的应用包括了一个用户界面,它还需要响应用户的操作,那么,你可能想产生一个独立的线程去读写.当服务器sockets形成一个blocking连接时,他们常常产生独立的线程给每一个客户连接,所以没有客户需要等待直到其他客户完成通过连接读或写操作.在默认情况下,服务器sockets使用TServerClientThread对象去实现为每个连接执行不同的线程.TServerClientThread对象模拟发生在non-blocking连接中的OnClientRead和OnClientWrite事件.可是,这些事件发生在监听socket上时,不是本地线程(thread-local).如果客户请求频繁,你将想建立你自己的TServerClientThread子类去提供一个安全线程(Thread-Safe)去完成读和写操作.
当写客户线程或写服务器线程时,你能够使用TwinSocketStream去做实际的读写操作.A)写客户端线程为客户端连接写一个线程,定义一个新线程对象,使用新线程对象对话框.你的新线程对象Execute方法的句柄的通过线程连接进行读写操作的细节,可以建立一个TWinSocketStream对象,然后使用它来读或写.使用你自己的线程,在OnConnect事件句柄中建立它.关于建立和运行线程的更多信息,请看Executing thread objects.例子:这个例子显示一个应用的客户线程在连接确定后向服务器发出写请求.void __fastcall TMyClientThread::Execute(){while (!Terminated && ClientSocket1->Active)// make sure connection is active{try{TWinSocketStream *pStream = new TWinSocketStream(ClientSocket1.Socket,60000);try{char buffer[10];GetNextRequest(buffer);// GetNextRequest must be a thread-safe method// write a request to the serverpStream->Write(buffer,strlen(buffer) + 1);// continue the communication (eg read a response)}__finally{delete pStream;}}catch (Exception &E){if (!E.ClassNameIs("EAbort"))Synchronize(HandleThreadException());// you must write HandleThreadException}}}B)写服务器线程服务器连接线程由TServerClientThread派生.因为这个,不能使用新线程对象对话框.替代的,手动声明你的线程如下:class PACKAGE TMyServerThread :public ScktComp::TServerClientThread{publicvoid __fastcall ClientExecute(void);}注意你将用重载ClientExcute方法替代Execute方法.执行ClientExecute方法必须为客户端连接写一个同样的Execute方法线程.然而,当你从控件栏上放一个客户socket控件到你的应用上时来替代这个方法时.监听服务socket同意一个连接时,服务客户线程必须使用TServerClientWinSocket对象来建立.这可以利用共公共的CientSocket属性.另外,你能够使用HandleException这个protected性的方法,胜过你自己写你的thread-safe例外操作.警告:Server sockets会缓存他们使用到的线程.确信ClientExecute方法执行一些必要的初始化操作,以便它们在最后执行时不致于产生不利的结果.当你使用你的线程时,在OnGetThread事件句柄中建立它.当建立线程,设置CreateSuspended参数为false.例子:这个例子显示一个为一个应用服务的线程,这个应用是在连接确定后由客户端来的读请求.void __fastcall TMyServerThread::ClientExecute(){while (!Terminated && ClientSocket->Connected)// make sure connection is active{try{TWinSocketStream *pStream = new TWinSocketStream(ClientSocket,60000);try{char buffer[10];memset(buffer, 0, sizeof(buffer));if (pStream->WaitForData(60000))// give the client 60 seconds to start writing{if (pStream->Read(buffer, sizeof(buffer) == 0)ClientSocket->Close();// if can't read in 60 seconds, close the connection// now process the request}elseClientSocket->Close();}__finally{delete pStream;}}catch (...){HandleException();}}}C.使用TwinSocketStream当为一个blocking连接实现一个线程时,你必须确定在连接的另一端的socket是准备写还是读.Blocking连接不会通知socket当它准备好写或读操作的时候.想看看连接是否准备好,使用TWinSocketStream对象.TWinSocketStream提供一个方法去帮助调整读或写操作时间的选择.调用WaitForData方法去等待,直到socket另一端的准备好写操作.当读写操作使用TWinSocketStream时,如果读或写操作在指定的时间期限内未能完成,Stream将发生超时.这个超时被当作一个结果,socket应用不会暂停,而是不断的通过一个dropped connection试图读或写.注意:你不能在non-blocking连接中使用TWinSocketStream