关于socket的问题

bjhua 2002-08-18 02:24:27
在客户端建立一个socket并bind之后,启动一个线程函数,在线程之内调用recv函数,如果服务器没有发送数据,此时这个线程会进入阻塞状态,我的问题是此时还可不可以针对这个socket调用send方法?(在java中,可以对一个socket调用getInputStream和getOutputStream获取输入流和输出流,对这两个流的操作互不影响。但在delphi中,针对一个socket创建了两个TWinSocketStream,当一个流进入阻塞状态时,令一个流似乎也不再可用,请问有无解决办法?因为我想在接收数据的同时仍然向服务器发送数据)
谢谢
...全文
12 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
cqjiang 2002-08-19
  • 打赏
  • 举报
回复
可以,因为发送和接受缓冲是分开的,而且你可以重新设置缓冲大小。
bjhua 2002-08-19
  • 打赏
  • 举报
回复
非常感谢蒋天书。那么我现在是否可以确认其实socket在同一时间内其实是单向的。也就是说,如果它在读数据(即正在调用recv),那么在读数据的操作完成之前,就不能再调用写数据的方法(send)?
cqjiang 2002-08-19
  • 打赏
  • 举报
回复
http://idoor.xiloo.com 有篇文章,《TCP/IP Winsock编程要点》里面讲了同时收发方法。
yxh_yzh 2002-08-19
  • 打赏
  • 举报
回复
当然不可以了。不过可以在非阻塞状态
bjhua 2002-08-19
  • 打赏
  • 举报
回复
这个问题已经找到答案。winsock的send和recv是双向的,但delphi中确实有上述问题,可能是delphi的控件有一些问题。
bjhua 2002-08-19
  • 打赏
  • 举报
回复
似乎不行啊(但在java里面确实是可以),如果你懂delphi,可以看看下面的代码。如果你有别的例子,发给我也行。



我写了下面的程序,但如果n := s_in.Read(buf[1],bufferSize);正在等待数据,那么
procedure TWorker.sendToServer(msg: String);
begin
msg := msg+ EOL;
s_out.Write(msg[1],Length(msg));
end;
就会也进入等待状态,这是为什么?


unit ClientUnit;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ConstUnit;

type
TWorker = class;
TForm2 = class(TForm)
mMsg: TMemo;
Edit1: TEdit;
btnSend: TButton;
procedure btnSendClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
worker:TWorker;
public
{ Public declarations }
procedure printMessage(msg:string);
end;

TWorker = class(TThread)
private
OutSocket,ClientSocket: TClientSocket;
socket:TCustomWinSocket;
s_in : TWinSocketStream;
s_out:TWinSocketStream;
public
procedure sendToServer(msg:String);
procedure Execute;override;
procedure Test;
constructor Create(createSuspended:boolean);
destructor Destroy;override;
end;
var
Form2: TForm2;

implementation

{$R *.dfm}

{ TWorker }

constructor TWorker.Create(createSuspended: boolean);
begin
ClientSocket := TClientSocket.Create(nil);
ClientSocket.Address := '10.8.6.70';
ClientSocket.Port := 8000;
ClientSocket.ClientType := ctBlocking;
ClientSocket.Active := true;
{
OutSocket := TClientSocket.Create(nil);
outSocket.Address := '10.8.6.70';
OutSocket.Port := 8000;
OutSocket.ClientType := ctBlocking;
OutSocket.Active := true;
}
socket := ClientSocket.socket;
self.FreeOnTerminate := true;
s_in := TWinSocketStream.Create(socket,60000);
s_out := TWinSocketStream.Create(socket,60000);
inherited Create(createSuspended);
end;

destructor TWorker.Destroy;
begin
s_in.Free;
s_out.Free;
ClientSocket.Close;
ClientSocket.Free;
//OutSocket.Close;
//OutSocket.Free;
end;

procedure TWorker.Execute;
var
buf,msg:string;
n:integer;
begin
//inherited;
//Form2.PrintMessage('Start Listening from server');
sendToServer('I have connected to u');
while socket.Connected do
begin
msg := '';
repeat
buf := '';
SetLength(buf,bufferSize);
n := s_in.Read(buf[1],bufferSize);
form2.printMessage('read bytes='+IntToStr(n));
if n = 0 then break;
SetLength(buf,n);
//form2.printMessage('+++++++++++++buf is '+buf);
msg := msg + buf;
until(Pos(EOL,buf)>0);

if msg <> '' then form2.printMessage('=========='+msg);
form2.printMessage('.........IDLE');
self.sendToServer('test');
//sleep(1300);
end;
end;

procedure TWorker.sendToServer(msg: String);
begin
msg := msg+ EOL;
s_out.Write(msg[1],Length(msg));
end;

procedure TWorker.Test;
begin
form2.printMessage('TWorker::Test');
end;

{ TForm2 }

procedure TForm2.printMessage(msg: string);
begin
mMsg.Lines.Add(msg);
end;

procedure TForm2.btnSendClick(Sender: TObject);
begin
worker.sendToServer(Edit1.Text);
//worker.Test;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
test:string;
begin
worker := TWorker.Create(False);
//worker.sendToServer(test);
//worker.Resume;
end;

end.
wjl_2001 2002-08-18
  • 打赏
  • 举报
回复
gz
99263 2002-08-18
  • 打赏
  • 举报
回复
阻塞与非阻塞到底谁的效率高呢?
bjhua 2002-08-18
  • 打赏
  • 举报
回复
非阻塞的编程模型是一种低效的办法,因为为了能够及时读取和发送数据,要不断的对缓冲区进行扫描,与其如此,还不如在一个线程中采用阻塞模式。再说,非阻塞的编程模型在某种意义上来说是不得已的情况下所采用的一种变通方式。
99263 2002-08-18
  • 打赏
  • 举报
回复
你采用非阻塞的方式不就可以了,就你现在所说的情况,我认为是可以发送的。

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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