阻塞模式常用在单通道Server自动响应收发数据里面,比如ClientA向ServerB发送报文,并且ClientA只需要它发送的这条数据ServerB对它有一个响应。其实c++ builder 里面阻塞模式的收发数据主要理解TWinSocketStream这个流。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
void
__fastcall TForm1::btn_1Click(TObject *Sender)
{
//1.初始化一些socket参数
ClientSocket1->Address=
"127.0.0.1"
;
ClientSocket1->Port=10101;
ClientSocket1->ClientType=ctBlocking;
//此处表示socket是阻塞模式
int
TIMEOUT=300000,MAXLENGTH=1024;
TWinSocketStream *pClientStream;
//TWinSocketStream to read or write information over a blocking socket connection
pClientStream=
new
TWinSocketStream(ClientSocket1->Socket,TIMEOUT);
//2.连接Server端
ClientSocket1->Open();
//3.发送数据
char
sendBuf[1024];
int
sendCount=0;
strcpy(sendBuf,E_send->Text.c_str()) ;
sendCount=pClientStream->Write(sendBuf,strlen(sendBuf)+1);
if
(sendCount==0) ShowMessage(
"发送失败!"
);
//4.接收数据
char
receiveBuf[1024];
int
Len=0;
if
(pClientStream->WaitForData(TIMEOUT))
//在TIMEOUT时间内如果没有接收到数据程序是直会在此挂起,因此如果阻塞模式接收数据的话一般放在线程里面
Len=pClientStream->Read(receiveBuf,MAXLENGTH);
receiveBuf[Len]=0;
Memo1->Lines->Add(receiveBuf);
}
|
使用多线程的阻塞模式要从一个TServerClientThread对象中派生一个类,在类的execute()方法中写收发数据的代码。收数据一般通过TWinSocketStream流实现。
这是派生的类的代码头
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//---------------------------------------------------------------------------
#ifndef UnitServerThreadH
#define UnitServerThreadH
//---------------------------------------------------------------------------
#include <ScktComp.hpp>
#include <StdCtrls.hpp>
#include "UnitMain.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
class
TServerThread :
public
TServerClientThread
{
protected
:
void
__fastcall ClientExecute(
void
);
int
__fastcall ReadStr(
char
* buf);
public
:
__fastcall TServerThread(
bool
CreateSuspended, TServerClientWinSocket* ASocket,HWND hWnd);
__fastcall ~TServerThread();
private
:
TWinSocketStream *pStream;
HWND m_hwnd;
};
#endif
|
//cpp文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
#include <vcl.h>
#pragma hdrstop
#include "UnitServerThread.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TServerThread::TServerThread(
bool
CreateSuspended, TServerClientWinSocket* ASocket,
HWND
hWnd) : TServerClientThread(CreateSuspended,ASocket)
{
m_hwnd=hWnd;
FreeOnTerminate=
false
;
}
//---------------------------------------------------------------------------
void
__fastcall TServerThread::ClientExecute(
void
)
{
//当一个客户连接的时候进入ClientExecute
//1.接收数据
try
{
pStream=
new
TWinSocketStream(ClientSocket,60000);
char
buf[1024];
memset
(buf,0,
sizeof
(buf));
try
{
int
len=0;
if
(pStream->WaitForData(60000))
{
len=pStream->Read(buf,1024);
buf[len]=0;
}
}
catch
(Exception &E)
{
}
//2.发送数据
ClientSocket->SendText(
"已经收到消息!消息为"
+AnsiString(buf));
}
__finally
{
ClientSocket->Close();
delete
pStream;
}
}
|
下面是主窗口代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "UnitMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ServerSocket1->Port=10101;
ServerSocket1->ServerType=stThreadBlocking;
//设置为阻塞模式
//指定缓存使用的线程的个数:如果第一个Client连接Server会自动生成一个TServerThread类对象
//当这个客户端断开时,这个对象不会释放,当第二个Cliet连接时,会重用这个TServerThread而不是
//重新创建此对象。ThreadCacheSize实际上指线程类不被释放的个数。
ServerSocket1->ThreadCacheSize=10;
//
ServerSocket1->Open() ;
}
//---------------------------------------------------------------------------
void
__fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
SocketThread=
new
TServerThread(
false
,ClientSocket,Form1->Handle);
}
//---------------------------------------------------------------------------
原文地址:http://www.cnblogs.com/zhangdongsheng/archive/2011/11/05/2236772.html
|