社区
网络及通讯开发
帖子详情
谁有线程中用阻塞方式实现的服务器代码,100分相赠
storm999
2005-10-06 04:21:10
如題
...全文
361
7
打赏
收藏
谁有线程中用阻塞方式实现的服务器代码,100分相赠
如題
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用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
最好有配套的客户端
redis del与unlink命令用法及
实现
本文详细对比了Redis中的DEL与UNLINK命令,解释了它们如何处理key的删除,尤其是在性能上的区别。DEL命令会
阻塞
服务器
直到完成,而UNLINK通过异步
方式
删除key,减少
阻塞
时间。文章还深入探讨了delGenericCommand函数的内部
实现
,以及如何评估内存释放成本,决定是否进行异步删除。
Delphi7.0自带Indy 9基础介绍
InternetDirect(Indy)是一组开放源
代码
的Internet组件,涵盖了几乎所有流行的Internet协议。Indy使用
阻塞
式Socket调用
方式
,这使得编程变得更加简单并且易于移植。文章详细介绍了Indy的
阻塞
式Socket的特点及如何通过TIdAntiFreeze组件解决用户界面冻结的问题。
数据结构与算法--使用Java
实现
数组队列和循环单链队列
本文深入讲解了队列这种数据结构的原理与应用,探讨了其存储结构,包括顺序存储(数组)和链式存储(链表)。并通过Java
代码
,演示了如何使用数组和循环单链表
实现
队列,对比了不同
实现
方式
的性能。
用Indy组件开发Socket应用程序
本文详细介绍了如何在Delphi中利用Indy组件开发TCP客户端和服务端应用程序,包括
阻塞
式Socket的优缺点、使用TIdAntiFreeze解决用户界面冻结问题、
线程
技术的应用以及一个简单的示例程序。
网络及通讯开发
1,317
社区成员
8,874
社区内容
发帖
与我相关
我的任务
网络及通讯开发
C++ Builder 网络及通讯开发
复制链接
扫一扫
分享
社区描述
C++ Builder 网络及通讯开发
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章