没有人回答吗?高手都到哪去了? 惨!惨! 两条贴共200分。 无忌兄你在哪! (100分)

  • 主题发起人 主题发起人 zheng
  • 开始时间 开始时间
Z

zheng

Unregistered / Unconfirmed
GUEST, unregistred user!
由于要减少服务端执行文件的大小,所以没有用到form。
服务端:
program PServer;

//{$APPTYPE CONSOLE}

uses
Windows,
Sysutils,
Winsock;

const MyPort = 6767;
SockVer = 514;

var Str: string;
Sockfd, Sockfd2: TSocket;
Rece: TWSAData;
Len: Integer;
Server: TSockAddr;
Buf: array[0..1023] of Char;
OptVal: Integer;
begin
try
if WSAStartup(SockVer, Rece) <> 0{SOCKET_ERROR} then
begin
MessageBox(0, 'WSAStartup fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

Sockfd := Socket(AF_INET, SOCK_DGRAM, 0);

if Sockfd < 0 then
begin
MessageBox(0, 'Socket fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

Server.Sin_Family := AF_INET;
Server.Sin_Port := htons(MyPort);
Server.Sin_Addr.S_addr := INADDR_ANY;

if Bind(Sockfd, Server, Sizeof(Server)) <> 0 then
begin
MessageBox(0, 'Bind fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

while (True) do
begin
Len := Recv(Sockfd, Buf, 1024, 0);
if Len > 0 then
begin
//Len := Send(NS, Buf, Len, 0); //返回数据
MessageBox(0, Buf, '接到信息', MB_ICONINFORMATION + MB_OK);
end;
end;

finally
WSACleanup();
MessageBox(0, '套接字结束', '调试', MB_ICONINFORMATION + MB_OK);
end;
end.

客户端:
unit ClientU1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Winsock;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

const MyPort = 6767;
SockVer = 514;

var Str: string;
Sockfd, Sockfd2: TSocket;
Rece: TWSAData;
Len: Integer;
SrvAddr: TSockAddr;
Buf: array[0..1023] of Char;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var OptVal: Integer;
begin
try
if WSAStartup(SockVer, Rece) <> 0 then
begin
MessageBox(0, 'WSAStartup fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

Sockfd := Socket(AF_INET, SOCK_DGRAM, 0);

if Sockfd < 0 then
begin
MessageBox(0, 'Socket fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

SrvAddr.Sin_Family := AF_INET;
SrvAddr.Sin_Port := htons(MyPort);
SrvAddr.Sin_Addr.S_addr := inet_addr('192.168.0.2');

{if Bind(Sockfd, Client, Sizeof(Client)) <> 0 then
begin
MessageBox(0, 'Bind fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end; }

Buf := 'Beej was here !';

Len := SendTo(Sockfd, Buf, StrLen(Buf), 0, SrvAddr, StrLen(Buf));

MessageBox(0, PChar(IntToStr(Len)), '调试', MB_ICONINFORMATION + MB_OK);
finally
WSACleanup();
end;

end;

end.

和“http://www.delphibbs.com/delphibbs/dispq.asp?lid=2214754”内容相同,回答任一条200分都得。
 
后来又改成这样,也不行:
program PServer;

uses
Windows, Messages, Classes, Sysutils, Winsock;

const MyPort = 6666;
SockVer = 514;
WM_UDP = WM_USER + 1;

type
TUDPThread = class(TThread)
private
FSockfd: TSocket;
FServer: TSockAddr;
protected
//procedure WndProc(var MsgRec: TMessage);
procedure Execute; override;
procedure ReadData(var Message: TMsg); message WM_UDP;
public
constructor Create;
destructor Destroy; override;
end;

constructor TUDPThread.Create;
var Rece: TWSAData;
begin
if WSAStartup(SockVer, Rece) <> 0{SOCKET_ERROR} then
begin
MessageBox(0, 'WSAStartup fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

FSockfd := Socket(AF_INET, SOCK_DGRAM, 0);

if FSockfd < 0 then
begin
MessageBox(0, 'Socket fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

FServer.Sin_Family := AF_INET;
FServer.Sin_Port := htons(MyPort);
FServer.Sin_Addr.S_addr := INADDR_ANY; //INADDR_ANY表示使用本机IP;如要直接赋值需用“inet_addr('192.168.0.1')”

if Bind(FSockfd, FServer, Sizeof(FServer)) <> 0 then
begin
MessageBox(0, 'Bind fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

if WSAAsyncSelect(FSockfd, Handle, WM_UDP, FD_READ or FD_ACCEPT or
FD_CONNECT or FD_WRITE or FD_CLOSE) <> 0 then
begin
MessageBox(0, 'WSAAsyncSelect fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

{if SetSockOpt(Sockfd, SOL_SOCKET, SO_BROADCAST, PChar(@OptVal),
Sizeof(OptVal)) <> 0 then
begin
MessageBox(0, 'SetSockOpt fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;}

{while (True) do
begin
Len := Recv(Sockfd, Buf, 1024, 0); //RecvLen为接收长度,若等于0表示断开联接,小于0表示失败
if Len > 0 then
begin
//Len := Send(NS, Buf, Len, 0); //返回数据
MessageBox(0, Buf, '接到信息', MB_ICONINFORMATION + MB_OK);
end;
end;}
end;

destructor TUDPThread.Destroy;
begin
MessageBox(0, '套接字结束', '调试', MB_ICONINFORMATION + MB_OK);
CloseSocket(FSockfd);
WSACleanup();
inherited Destroy;
end;

procedure TUDPThread.Execute;
var Msg: TMsg;
begin
while GetMessage(Msg, 0, 0, 0) do
begin
if Msg.Message = WM_UDP then
ReadData(Msg);
end;
end;

procedure TUDPThread.ReadData(var Message: TMsg);
var Buf: array[0..1023] of Char;
Len: Integer;
begin
Len := Recv(FSockfd, Buf, 1024, 0); //RecvLen为接收长度,若等于0表示断开联接,小于0表示失败
if Len > 0 then
begin
//Len := Send(NS, Buf, Len, 0); //返回数据
MessageBox(0, Buf, '接到信息', MB_ICONINFORMATION + MB_OK);
end;
end;


var UDPThread: TUDPThread;
begin
UDPThread := TUDPThread.Create;
UDPThread.Execute;
MessageBox(0, 'OK', '调试', MB_ICONINFORMATION + MB_OK);
UDPThread.Free;
end.
 
是做木马吗?呵呵~~~~,这样不太好吧,呵呵~~
 
老兄,你只管把代码往上面一丢,然后等着别人去帮你测试,而你却一点错误原因或错误状况都不描述,你叫人怎么回答?
线程阻塞模式和异步事件模式的示例源码我都有,要的话留下信箱,我发给你,你自个琢磨吧。
 
to ego:

关键就在于由于没有Form、Applincation,没有窗口不知怎样得到UDP的接收消息,所以
不知道用什么代码在什么时候去recv。
WSAAsyncSelect(FSockfd, Handle......)这里的句柄用的是线程的,并不是窗口所以老是
不能得到正确的返回值,说明WSAAsyncSelect不成功。

另:请看"http://www.delphibbs.com/delphibbs/dispq.asp?lid=2214754"

Email: zhengxq@21cn.com
 
张无忌国庆假期正在忙一个软件,连MM都没时间见...[:D]
 
线程阻塞模式是不需要窗体的,可以在控制台程序中正常工作。
我没试过在控制台中使用WSAAsyncSelect模式,但我想用WSAEventSelect模式可能更适合。
 
呵呵,贴个最简单的WSAEventSelect模式的例子吧。这是以前偶测试用的,只是个大概框架,功能和稳定都不完善,你修改一下吧,修改好后发给偶一份 ^_^

//用WSAEventSelect模式的好处在于,只用两个线程(一个处理事件,另一个处理发送),就可以完成数据处理。
//相对于Block模式来说,WSAEventSelect节省了大量的线程资源;
//相对于WSAsyncSelect(异步选择)模式来说,WSAEventSelect可以在控制台模式下运行,但WSASyncSelect有一个弊端:
//当数据交换太过于频繁时,窗体的消息可能会因为响应不及时而丢失。
//但WSAEventSelect也有一个限制:因为使用WSAWaitForMultipleEvents来响应网络事件,所以每个接受线程只能处理
//64个套接字,多于64(的倍数)时必须再新建一个线程来处理。
//同样的限制在WSASyncSelect中也一样。

unit MainServer;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Winsock2, Global, SyncObjs;

type
TMainForm = class(TForm)
btnStartup: TButton;
Memo: TMemo;
btnClearup: TButton;
btnClose: TButton;
edit: TEdit;
btnSend: TButton;
cmbUserID: TComboBox;
Label1: TLabel;
procedure btnStartupClick(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
procedure btnSendClick(Sender: TObject);
private

public
{ Public declarations }
end;

TServerThread = class(TThread)
public
procedure execute; override;
end;

var
MainForm: TMainForm;
EventTotal: DWord;
SocketArray: array [0..wsa_maximum_wait_events-1] of TSocket;
EventArray: array [0..wsa_maximum_wait_events-1] of WSAEvent;
NewEvent: TWSAEvent;
NetWorkEvents: PWSANetWorkEvents;
AcceptSocket, ListenSocket: TSocket;
buf: TBuf;

implementation

{$R *.dfm}

procedure TMainForm.btnStartupClick(Sender: TObject);
var
wsaData: TWSAData;
ServerAddr: TSockAddrIn;
begin
EventTotal := 0;

Memo.Lines.add('Startup...');
WSAStartup(MakeWord(2,2), wsaData); //启动Winsock

Memo.Lines.Add('socket...');
ListenSocket := socket(AF_INET, Sock_Stream, IPProto_TCP); //建立监听socket
if ListenSocket = socket_error then
raise exception.Create(IntToStr(GetLastError));

Memo.Lines.Add('bind...');
ServerAddr.sin_family := AF_INET;
ServerAddr.sin_port := htons(port);
ServerAddr.sin_addr.S_addr := htonl(INADDR_ANY);
if bind(ListenSocket, @ServerAddr, SizeOf(ServerAddr)) = socket_error then //绑定
raise exception.Create(IntToStr(GetLastError));

NewEvent := WSACreateEvent(); //建立监听套接字事件

//选择要响应的事件消息(开始只响应接受消息,read和write消息在响应accept之后再select)
WSAEventSelect(ListenSocket, NewEvent, fd_accept or fd_close);

Memo.Lines.Add('listen...');
if listen(ListenSocket, 5) = socket_error then //监听
raise exception.Create(IntToStr(GetLastError));

SocketArray[EventTotal] := ListenSocket; //关联监听,以便响应事件
EventArray[EventTotal] := NewEvent;
inc(EventTotal);

new(NetWorkEvents);

TServerThread.create(false);
end;

procedure TMainForm.btnCloseClick(Sender: TObject);
begin
close;
end;

{ TServerThread }

procedure TServerThread.execute;
var
index, i: DWord;
ClientAddr: PSockAddrIn;
AddrLen: PInteger;
begin
new(ClientAddr);
new(AddrLen);

while not Terminated do
begin

//等候所有套接字上的网络事件。
index := WSAWaitForMultipleEvents(EventTotal, @EventArray, false, wsa_infinite, false);
dec(index, wsa_wait_event_0);

//遍历所有事件,查看被传信的事件是否多于一个
for i := index to EventTotal - 1 do
begin
index := WSAWaitForMultipleEvents(1, @EventArray, true, 1000, false);

if (index = wsa_wait_failed) or (index = wsa_wait_timeout) then
continue
else
begin
index := i;

//枚举发生的事件
WSAEnumNetWorkEvents(SocketArray[index], EventArray[index], NetWorkEvents);

//检查fd_accept消息
if NetworkEvents.lNetworkEvents = fd_accept then
begin
if NetworkEvents.iErrorCode[fd_accept_bit] <> 0 then //iErrorCode的错误代码在帮助中详细描述
begin
MainForm.memo.Lines.Add(format('fd_accept failed with error %d', [NetworkEvents.iErrorCode[fd_accept_bit]]));
break;
end;

//接受一个新连接,并将它添加到套接字及事件列表中
//注意:有时候accept会返回一个很大的数值(正常数值应该是从140左右开始的),
//但系统并不报错,而实际上返回AcceptSocket是无效的socket
AcceptSocket := Accept(SocketArray[index], ClientAddr^, AddrLen^);

//由于WSAWaitForMultipleEvents函数最多只能处理64个事件对象,故关闭接受套接字
if EventTotal > wsa_maximum_wait_events then
begin
MainForm.memo.Lines.Add('Too many connections');
CloseSocket(AcceptSocket);
break;
end;

NewEvent := WSACreateEvent(); //建立接收和发送套接字事件对象

//为刚才接受建立的Socket选择要响应的事件
WsaEventSelect(AcceptSocket, NewEvent, fd_read or fd_write or fd_close);

//把接受的socket存到数组中
EventArray[EventTotal] := NewEvent;
SocketArray[EventTotal] := AcceptSocket;

inc(Eventtotal);
MainForm.memo.Lines.Add(format('SocketHandle %d connected', [AcceptSocket]));

end;

//处理fd_read通知
if NetworkEvents.lNetworkEvents = fd_read then
begin

if NetworkEvents.iErrorCode[fd_read_bit] <> 0 then
begin
MainForm.memo.Lines.Add(format('fd_read failed with error %d', [NetworkEvents.iErrorCode[fd_read_bit]]));
break;
end;

if recv(SocketArray[index - wsa_wait_event_0], buf, bufsize, 0) = socket_error then //从套接字读入数据
raise exception.Create(IntToStr(GetLastError))
else
begin
MainForm.Memo.Lines.Add('[收到消息]' + buf.Msg);
if Send(SocketArray[buf.DestID + 1], buf, bufsize, 0) = socket_error then //转发
raise exception.Create(IntToStr(GetLastError))
else
MainForm.Memo.Lines.Add('[转发消息]' + buf.Msg);
end;

end;

if NetworkEvents.lNetworkEvents = fd_write then
begin

if NetworkEvents.iErrorCode[fd_write_bit] <> 0 then
begin
MainForm.memo.Lines.Add(format('fd_write failed with error %d', [NetworkEvents.iErrorCode[fd_write_bit]]));
break;
end;

buf.DestID := 0;
buf.Msg := 'Hello!Welcome to Server!';
buf.MsgType := stMsg;
buf.SourceID := 0;
send(SocketArray[index - wsa_wait_event_0], buf, bufsize, 0);

end;

//处理关闭事件
if NetworkEvents.lNetworkEvents = fd_close then
begin

if NetworkEvents.iErrorCode[fd_close_bit] <> 0 then
begin
MainForm.memo.Lines.Add(format('fd_close failed with error %d', [NetworkEvents.iErrorCode[fd_close_bit]]));
break;
end;

CloseSocket(SocketArray[index]);
end;

end;
end; //for

end; //while

dispose(ClientAddr);
dispose(AddrLen);
end;

procedure TMainForm.btnSendClick(Sender: TObject);
var
buf: TBuf;
begin
if cmbUserID.ItemIndex = -1 then
cmbUserID.ItemIndex := 0;
if SocketArray[cmbUserID.ItemIndex] = 0 then
memo.Lines.Add(IntToStr(cmbUserID.ItemIndex) + ' is nil');
buf.DestID := 0;
buf.Msg := edit.Text;
buf.MsgType := stMsg;
buf.SourceID := -1;

if Send(SocketArray[cmbUserID.ItemIndex + 1], buf, bufsize, 0) = socket_error then
raise exception.Create(IntToStr(GetLastError))
else
memo.Lines.Add('[发送到' + IntToStr(cmbUserID.ItemIndex) + ']' + edit.Text);
end;

end.
 
to ego:
我看看先!
 
还是不行,有几句看不明白:

WSAWaitForMultipleEvents(1, @EventArray, true, 1000, false);

WSAEnumNetWorkEvents(FSockfd, FNewEvent, NetWorkEvents);

能够相应UDP动作的机理我还不明白,另外你给的是TCP的,这个比较容易解决一点,或者说
我已经知道怎样响应,因为它有Listen和Accept等,而我这里的UDP就没有,我不知道怎样解决?
 
将我又改了一次的代码附下(还是没有解决怎样相应客户端发来的报文的事件,所以也就接收不到):

客户端:
unit ClientU1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Winsock2;

const UDPPort = 8888;
SockVer = 514;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;


implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var Sockfd: TSocket;
Rece: TWSAData;
SrvAddr: TSockAddrIn;
Buf: array[0..1023] of Char;
SLen: Integer;
bFlag: Bool;
begin
try
if WSAStartup(SockVer, Rece) <> 0 then
begin
MessageBox(0, 'WSAStartup fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

Sockfd := Socket(AF_INET, SOCK_DGRAM, IPProto_UDP); //IPProto_UDP

if Sockfd < 0 then
begin
MessageBox(0, 'Socket fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

SrvAddr.Sin_Family := AF_INET;
SrvAddr.Sin_Port := htons(UDPPort);
SrvAddr.Sin_Addr.S_addr := inet_addr('192.168.0.2');

bFlag := True; //设置套接字选项,使套接字为可重用端口地址
if SetSockOpt(Sockfd, SOL_SOCKET, SO_REUSEADDR, @bFlag, Sizeof(bFlag)) <> 0 then
begin
MessageBox(0, 'SetSockOpt fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

Buf := 'Beej was here !';
SLen := StrLen(Buf);
////////////////////
if SendTo(Sockfd, Buf, SLen, 0, @SrvAddr, Sizeof(SrvAddr)) = Socket_Error then
MessageBox(0, 'Send fail', '调试', MB_ICONINFORMATION + MB_OK);
finally
WSACleanup();
end;
end;

end.

******************************************
服务端:
program PServer;

uses
Windows, Messages, Classes, Sysutils, {Winsock,} WinSock2;

const UDPPort = 5555;
SockVer = 514;
//MaxEvent = WSA_MAXIMUM_WAIT_EVENTS;
type
TUDPThread = class(TThread)
private
FSockfd: TSocket;
FFromAddr: TSockAddrIn;
FNewEvent: TWSAEvent;
protected
procedure Execute; override;
public
constructor Create; virtual;
destructor Destroy; override;
end;

constructor TUDPThread.Create;
var Rece: TWSAData;
bFlag: Bool;
begin
if WSAStartup(SockVer, Rece) <> 0{SOCKET_ERROR} then
begin
MessageBox(0, 'WSAStartup fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

FSockfd := Socket(AF_INET, SOCK_DGRAM, 0);

if FSockfd < 0 then
begin
MessageBox(0, 'Socket fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

bFlag := True; //设置套接字选项,使套接字为可重用端口地址
if SetSockOpt(FSockfd, SOL_SOCKET, SO_REUSEADDR, @bFlag, Sizeof(bFlag)) <> 0 then
begin
MessageBox(0, 'SetSockOpt fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

{
FFromAddr.Sin_Family := AF_INET;
FFromAddr.Sin_Port := htons(UDPPort);
FFromAddr.Sin_Addr.S_addr := htonl(INADDR_ANY);

if Bind(FSockfd, @FServer, Sizeof(FServer)) <> 0 then
begin
MessageBox(0, 'Bind fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;
}

FNewEvent := WSACreateEvent(); //建立监听套接字事件

if WSAEventSelect(FSockfd, FNewEvent, FD_READ or FD_WRITE or FD_CLOSE) <> 0 then
begin
MessageBox(0, 'WSAEventSelect fail', '调试', MB_ICONINFORMATION + MB_OK);
Exit;
end;

inherited Create(False);
end;

destructor TUDPThread.Destroy;
begin
CloseSocket(FSockfd);
WSACleanup();
inherited Destroy;
end;

procedure TUDPThread.Execute;
var NetWorkEvents: PWSANetWorkEvents;
Buf: array[0..1023] of Char;
BufSize, FromAddrSize: Integer;
begin
while True do //not Terminated
begin
//////////////////////////
WSAWaitForMultipleEvents(1, @FNewEvent, True, WSA_INFINITE, False);

WSAEnumNetWorkEvents(FSockfd, FNewEvent, NetWorkEvents); //枚举发生的事件

if NetworkEvents.lNetworkEvents = FD_READ then //处理FD_Read通知
begin
MessageBox(0, 'FD_Read!', '调试', MB_ICONINFORMATION + MB_OK);
if NetworkEvents.iErrorCode[FD_READ_BIT] <> 0 then
begin
MessageBox(0, 'FD_Read failed', '调试', MB_ICONINFORMATION + MB_OK);
Break;
end;
/////////////////////
FromAddrSize := Sizeof(FFromAddr);
if RecvFrom(FSockfd, Buf, BufSize, 0, @FFromAddr, FromAddrSize) = Socket_Error then //从套接字读入数据
raise Exception.Create(IntToStr(GetLastError()))
else begin
MessageBox(0, Buf, '调试', MB_ICONINFORMATION + MB_OK);
{if Send(FSockfd, Buf, BufSize, 0) = Socket_Error then //转发
raise Exception.Create(IntToStr(GetLastError()))}
end;
end;

if NetworkEvents.lNetworkEvents = FD_Close then //处理关闭事件
begin
if NetworkEvents.iErrorCode[FD_CLOSE_BIT] <> 0 then
begin
MessageBox(0, 'FD_Close failed', '调试', MB_ICONINFORMATION + MB_OK);
Break;
end;
CloseSocket(FSockfd);
MessageBox(0, '套接字结束', '调试', MB_ICONINFORMATION + MB_OK);
end;
end; //End While
end;


//*******************************************************************//
var UDPThread: TUDPThread;

begin
UDPThread := TUDPThread.Create;
UDPThread.Free;
end.
 
麻烦、麻烦帮我看看代码错在哪?!!!!!!!!!!!!!?
 
to tseug:
无忌兄什么时候才有空,焦急等待!希望他能够有耐心帮我!

to ego:
你最好能够给我解释一下
WSACreateEvent()、WSAEventSelect()、WSAWaitForMultipleEvents()、
WSAEnumNetWorkEvents()这几个函数为什么能够实现类似windows消息机制的
原理,以及和Thread线程的配合,究竟是为了效率而使用Thread还是因为
WSAEventSelect这些机制一定要用Thread,我看你的代码都看不出Thread的
作用,难道只是弄出很多个可以发信息的UDP连接而不执行同一目的有用吗?
多线程执行同一个目的或者说同一件事而提高效率才是有用的吧?不知道是
我看不明白,理解错你的作用,还是你就是这样想的。
 
UDP连接偶没试过,我这有一个UDP例子,但是C++的,要不要?
推荐你看一本书《Windows网络编程》,你想知道的东东这本书里都有。而且第5章里每一种连接模式都有详细解说和简单示例。呵呵,偶说得再仔细也没这本书详细,而且很多东东偶也不太明白 ^_^
PS:偶在MSN上呼了张无忌,但他没回应 :(
 
《Windows网络编程》是不是用C++写的,我对它C++很生,很多都看不明白,不过我
也准备去买本类似的来看看,没办法就只能去啃C++了,因为用Delphi写的恐怕一本
都没有。不过你先把C++的例子给我,总不能让我等到买书看完后再完成这个吧,现在
是临机抱佛脚。
噢差点忘了问这本书是那个出榜社的。
 
能不能快点给我回复,谢谢!
 
唉,你就简单讲讲你给我的Tcp代码里的多线程是什么意思和原理。
看我上面的:
TUDPThread.Execute里的
while True do 循环,这样有什么问题?
 
那本书是清华出版社出版的。
唉,如果你很急,而且你的服务器的负荷不是很大,干脆用阻塞模式算了,最简单,只要会多线程就可以了。
 
问题是我到现在都不知道怎么用,包括阻塞模式,都不知道怎么样在没有form的情况下
接受到发送到的信号?用什么办法来获得?
 
后退
顶部