c++ builder 阻塞模式 socke 教程 说明

1.Client端

阻塞模式常用在单通道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);
 
 
}

2.Server端(TServerSocket 多线程阻塞模式收发数据)

使用多线程的阻塞模式要从一个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);
}
//-----------------


上一篇:记:MySQL 5.7.3.0 安装 全程截图


下一篇:阿里云圣诞气氛组,申请出战!