看看我的阻塞Socket通信。(100分)

  • 主题发起人 主题发起人 windlike
  • 开始时间 开始时间
W

windlike

Unregistered / Unconfirmed
GUEST, unregistred user!
用C++Builder4.0(与Delphi应该是差不多的)编了一个阻塞的应用.ServerSocket为stThreadBlocking,ClientSocket为ctBlocking.
Client端先发送一个命令(2byte长)给Server,Server接受命令,并
发回数据给Client端。程序如下。
Client:
void __fastcall TMainForm::Button2Click(TObject *Sender)
{
char buf[2];
strncpy(buf,Edit2->Text.c_str(),2);
ClientSocket1->Open();
TWinSocketStream * pStream = new TWinSocketStream(ClientSocket1->Socket,60000);
int i;
i=pStream->Write((void*)buf,2);
delete pStream;
}
执行完可以看到i=2.
Server端如下:
void __fastcall TMainForm::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
char *Buffer;
char Command[2];
char *SendBuf;
int size;
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket1->Socket,60000);
size = pStream->Size;
Buffer =(char *)malloc(pStream->Size);
if (!pStream->WaitForData(60000)){
delete pStream;//每次都进这里了
return;
}
pStream->Read(Buffer,pStream->Size);
。。。
}
执行到这里size为0.然后每次都在if处进去了
pStream->Read执行不了。
到底怎么回事呢?
请各位高人指点。
多谢了。越快越好

 
我对你使用pStream->Read(Buffer,pStream->Size);感到怀疑。因为
在接收端是不可能知道发送端会发送什么数据的。
我这里有一段代码,从我以前的程序中摘录的,或者有帮助:
void __fastcall TRmtSvr::ServerSocketGetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
SocketThread = new TRmtSvrThread(false, ClientSocket); // 响应客户信息,启动一个线程。
}
void __fastcall TRmtSvrThread::ClientExecute()
{
while(!Terminated && ClientSocket->Connected) {
try {
SocketStream = new TWinSocketStream(ClientSocket, 6000000);
try {

Size = 0; // 将要接收的数据的大小
prefix_bytes_read = 0; // 已经读入的数据头的字节数
new_bytes_read = 0;
char temp_buf[prefix_size + 1]; // 储存数据头

// 读入数据头
// 数据头是为了告诉程序后面还有多少数据要读,多的数据是下一条消息的,
// 如果少于这些字节,那么等待
while(prefix_bytes_read < prefix_size && ClientSocket->Connected) {
new_bytes_read = SocketStream->Read(temp_buf + prefix_bytes_read, prefix_size - prefix_bytes_read);
if(new_bytes_read >= 1) {
prefix_bytes_read += new_bytes_read;
}
else {
ClientSocket->Close();
Terminate();
}
}

temp_buf[prefix_size] = '/0';
Size = StrToInt(temp_buf);
char* Data = new char[Size + 1]; // 这才是我们实际需要的数据
packet_bytes_read = 0;
// 按照刚才收到的数据头的信息读入数据
while(packet_bytes_read < Size && ClientSocket->Connected) {
new_bytes_read = SocketStream->Read(Data + packet_bytes_read, Size - packet_bytes_read);
if(new_bytes_read >= 1) {
packet_bytes_read += new_bytes_read;
}
else {
ClientSocket->Close();
Terminate();
}
}

Data[Size] = '/0';
// 处理读入的信息,注意 ProcessMsg() 要 Thread-safe
if(ClientSocket->Connected)
ProcessMsg(Data, Size);

delete Data;
Data = 0;
}
__finally {
delete SocketStream;
}
}
catch(...) {
throw;
}
}
}

我对 Blocking 编成也很感兴趣,希望可以一起探讨。
 
我是delphi的该多好啊!!
 
It is not necessary for you to know the count of data,and even when the BUFFER_SIZE = 1 this method of the thread can work correctly.

procedure TMyServerClientThread.ClientExecute;
var
SocketStream: TWinSocketStream;
MemoryStream: TMemoryStream;
p: PChar;
NewBytesRead: Integer;
begin
SocketStream := nil;
MemoryStream := nil;
p := nil;

try
GetMem(p, BUFFER_SIZE);
SocketStream := TWinSocketStream.Create(ClientSocket, 600000);
MemoryStream := TMemoryStream.Create;

while (not Terminated) and ClientSocket.Connected do
try
NewBytesRead := SocketStream.Read(p^, BUFFER_SIZE);

if NewBytesRead >= 1 then
MemoryStream.Write(p^, NewBytesRead)
else
begin
ClientSocket.Close;
Terminate;
end;
finally
end;
finally
MemoryStream.SaveToFile('e:/temp/ookk.txt');
MemoryStream.Free;
SocketStream.Free;
FreeMem(p);
end;
end;
 
Wilbur:
能否把TRmtSvrThread的定义贴上来?
 
class TRmtSvrThread : public TServerClientThread {
private:
void SendMsg(TMsgId Aid, AnsiString AString);
void SendMsg(TMsgId Aid, TStream* AStream);
public:
__fastcall TRmtSvrThread(bool suspended, TServerClientWinSocket* ASocket);
__fastcall ~TRmtSvrThread(void);

virtual void __fastcall ClientExecute(void);

void ProcessMsg(char* Data, int length);
};
 
接受答案了.
 
后退
顶部