谁有线程中用阻塞方式实现的服务器代码,100分相赠

storm999 2005-10-06 04:21:10
如題
...全文
361 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
storm999 2005-10-07
  • 打赏
  • 举报
回复
这个贴结掉﹐我重开一帖 "季老大请进" 请在新贴上赐教
storm999 2005-10-07
  • 打赏
  • 举报
回复
例子已收到﹐非常感谢
我开始也写了一个阻塞的程序﹐程序也是继承了TserverClientThread类﹐重载了ClientExecute方法﹐使用TwinSocketStream收数据﹐可只有在ClientSocket调用Open方法时才能收到数据﹐用SendBuffer方法发送的数据服务都收不到﹐不知这是怎么回事﹗
jishiping 2005-10-07
  • 打赏
  • 举报
回复
上面的例子,class SrvThread 是用来接收数据的,class ClientThread是用来发送数据的,发送、接收的数据格式自己定义。在我这儿,先发送4个字节(DWORD,存放文件的长度),然后才发送文件的内容。接收端就是先接收4个字节(文件爱女的长度),然后再接收文件的内容。这样接收端通过一开始读到的文件长度以及后来接收的数据长度,就知道数据是否接收完整了。当然了,你也可以定义你自己的格式,比如一开始发送(接收)的256(或者512)个字节存放文件名,然后才是文件的长度和内容。
jishiping 2005-10-07
  • 打赏
  • 举报
回复
class TForm1 : public TForm
{
__published: // IDE-managed Components
TServerSocket *ServerSocket1;
TOpenDialog *OpenDialog1;
TGroupBox *GroupBox1;
TLabel *Label1;
TEdit *SrvPort;
TUpDown *UpDown1;
TButton *ListenBtn;
TGroupBox *GroupBox2;
TLabel *Label2;
TEdit *IPAddr;
TLabel *Label3;
TEdit *ClientPort;
TButton *SendBtn;
void __fastcall ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall SendBtnClick(TObject *Sender);
void __fastcall ListenBtnClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};

class SrvThread : public TServerClientThread
{
private:
UINT FTimeOut;
TWinSocketStream* WskStream;
protected:
void __fastcall ClientExecute();
public:
__fastcall SrvThread(TServerClientWinSocket*);

__property UINT TimeOut = { read=FTimeOut, write=FTimeOut };
};

class ClientThread : public TThread
{
private:
AnsiString File;
TClientSocket* ClientSocket;
TWinSocketStream* WskStream;
protected:
void __fastcall Execute();
public:
__fastcall ClientThread(AnsiString IPAddr,
WORD Port, AnsiString file);
};

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
ServerSocket1->Active = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
SocketThread = new SrvThread(ClientSocket);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListenBtnClick(TObject *Sender)
{
ServerSocket1->Port = SrvPort->Text.ToInt();
ServerSocket1->Active = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SendBtnClick(TObject *Sender)
{
int Port;
AnsiString Addr;

Addr = IPAddr->Text.Trim();
if (Addr.IsEmpty()) {
IPAddr->SetFocus(); return;
}
try {
Port = ClientPort->Text.ToInt();
}
catch(Exception& e) {
ShowMessage(e.Message);
ClientPort->SetFocus(); return;
}
if (OpenDialog1->Execute())
new ClientThread(Addr, Port,
OpenDialog1->FileName);
}
//-----------------------------------------------------------
__fastcall SrvThread::SrvThread(TServerClientWinSocket* socket)
: TServerClientThread(false,socket)
{
}
//---------------------------------------------------------
//示范程序里,收到的数据写到文件"test*.dat"
void __fastcall SrvThread::ClientExecute()
{
int nLen;
int nSize;
int hFile;
char buf[4096];
static int num=0;

TimeOut = 60000; //60秒
WskStream = new TWinSocketStream(
ClientSocket, TimeOut);

while(1) {
wsprintf(buf, "test%04x.dat",
num++);
if (!FileExists(buf)) {
hFile = FileCreate(buf);
if (hFile!=-1) break;
}
}
try {
DWORD dwTick = GetTickCount();
//先读取发送的文件长度
if (WskStream->WaitForData(
TimeOut)) {
nLen = WskStream->Read(
&nSize, 4);
if (nLen!=4) nSize = 0;
}
else
nSize = 0;
//然后读取文件数据
for(; nSize>0 && !Terminated;
nSize-=nLen) {
if (!WskStream->WaitForData(
5000)) {
if (GetTickCount()-dwTick
<TimeOut)
continue;
//在规定时间内没有收到数据,
//结束线程
break;
}
nLen = WskStream->Read(buf,
sizeof(buf));
dwTick = GetTickCount();
if (nLen <= 0) {
//读数据出错,这儿做一些
//处理
break;
}
//添加收到数据的处理,这儿写到
//文件 test*.dat 中 ...
FileWrite(hFile, buf, nLen);
}
if (ClientSocket->Connected)
ClientSocket->Close();
}
catch(Exception& e) {
MessageBox(0, e.Message.c_str(),
"Error", MB_ICONERROR);
}
FileClose(hFile); delete WskStream;
}
//---------------------------------------------------------------------------
__fastcall ClientThread::ClientThread(AnsiString IPAddr,
WORD Port, AnsiString file)
: TThread(true) //先将线程挂起,给线程初始化后再运行
{
File = file; WskStream = NULL;
ClientSocket = new TClientSocket(NULL);
ClientSocket->ClientType = ctBlocking;
ClientSocket->Host = IPAddr;
ClientSocket->Port = Port;
Resume(); //初始化后,让线程继续执行
}

void __fastcall ClientThread::Execute()
{
int nLen;
int hFile;
int nSize;
char buf[4096];

try {
hFile = -1;
ClientSocket->Active = true;
WskStream = new TWinSocketStream(
ClientSocket->Socket, 60000);
hFile = FileOpen(File, fmOpenRead);
if (hFile != -1) {
nSize = GetFileSize((HANDLE)
hFile, NULL);
//先发送文件长度
WskStream->Write(&nSize, 4);
//然后发送文件数据
for(; nSize>0; nSize-=nLen) {
nLen = min((int)sizeof(
buf), nSize);
nLen = FileRead(hFile, buf,
nLen);
if (nLen<=0) break;
WskStream->Write(buf, nLen);
}
}
ClientSocket->Active = false;
}
catch(Exception& e) {
MessageBox(0, e.Message.c_str(),
"Error", MB_OK|MB_ICONERROR);
}
delete WskStream; delete ClientSocket;
if (hFile!=-1) FileClose(hFile);
}
jishiping 2005-10-07
  • 打赏
  • 举报
回复
发了一个例子。
storm999 2005-10-07
  • 打赏
  • 举报
回复
up
storm999 2005-10-06
  • 打赏
  • 举报
回复
我的EMail是999zhaorui@163.com
最好有配套的客户端

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧