如题. 小弟这样处理效果很不理想, 不使用UDP控件(打包麻烦)如何广播传输? ServerSocket1.Socket.Lock;
ConnectCount:= ServerSocket1.Socket.ActiveConnections;
for i:=0 to ConnectCount-1 do ServerSocket1.Socket.Connections[i].SendText('...');
ServerSocket1.Socket.Unlock;
ConnectCount:= ServerSocket1.Socket.ActiveConnections;
for i:=0 to ConnectCount-1 do ServerSocket1.Socket.Connections[i].SendText('...');
ServerSocket1.Socket.Unlock;
indy控件也可以
要不就用win socket 自己写
我用过UDP 比较麻烦, 懒得改了.
uses
Windows, Winsock, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls;const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPORT = 6543; //设定UDP端口号
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
GroupBox1: TGroupBox;
Label2: TLabel;
Label3: TLabel;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
s: TSocket;
addr: TSockAddr;
FSockAddrIn: TSockAddrIn;
//mreq:ip_mreq;
//利用消息实时获知UDP消息
procedure ReadData(var Message: TMessage); message WM_SOCK;
public
{ Public declarations }
procedure SendData(Content: string);
end;var
Form1: TForm1;implementation{$R *.dfm}{ TForm1 }function LocalIP: string;
type
TaPInAddr = array[0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
Buffer: array[0..63] of char;
I: Integer;
GInitData: TWSADATA;begin
WSAStartup($101, GInitData);
Result := '';
GetHostName(Buffer, SizeOf(Buffer));
phe := GetHostByName(buffer);
if phe = nil then
Exit;
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^[I] <> nil do
begin
result := StrPas(inet_ntoa(pptr^[I]^));
Inc(I);
end;
WSACleanup;
end;procedure TForm1.ReadData(var Message: TMessage);
var
buffer: array[1..4096] of char;
len: integer;
flen: integer;
Event: word;
value: string;
ResultInf: TStringList;
begin
flen := sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(UDPPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
value := copy(buffer, 1, len);
Memo1.Lines.add(value); if value = 'Server' then
if CheckBox1.Checked then //如果当前是服务器,则返回确认消息
begin
try
ResultInf := TStringList.Create;
ResultInf.Values['IP'] := LocalIP;
ResultInf.Values['Port'] := '123';
senddata(ResultInf.CommaText);
finally
ResultInf.Free;
end;
end;
end;
end;procedure TForm1.SendData(Content: string);
var
value {,hostname}: string;
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := INADDR_BROADCAST;
//FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(Edit1.text)); //INADDR_BROADCAST; //INADDR_BROADCAST = -1 ?
value := Content;
len := sendto(s, value[1], Length(value), 0, FSockAddrIn,
sizeof(FSockAddrIn));
if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then
showmessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then
showmessage('send fail');
if len <> Length(value) then
showmessage('Not Send all');end;procedure TForm1.FormCreate(Sender: TObject);
var
TempWSAData: TWSAData;
optval: integer;
begin
// 初始化SOCKET
if WSAStartup($101, TempWSAData) = 1 then
showmessage('StartUp Error!'); s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
showmessage(inttostr(WSAGetLastError()) + ' Socket创建失败');
CloseSocket(s);
//exit;
end;
//发送方SockAddr绑定
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := INADDR_ANY;
addr.sin_port := htons(UDPPORT);
if Bind(s, addr, sizeof(addr)) <> 0 then
begin
showmessage('bind fail');
end; optval := 1;
if setsockopt(s, SOL_SOCKET, SO_BROADCAST, pchar(@optval), sizeof(optval)) =
SOCKET_ERROR then
begin
showmessage('无法进行UDP广播');
end; {mreq.imr_multiaddr.S_addr := INADDR_ALLHOSTS_GROUP;
mreq.imr_interface.S_addr := INADDR_ANY;
if setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,pchar(@mreq),sizeof(mreq)) = SOCKET_ERROR then
begin
showmessage('无法进行UDP组播');
end;} WSAAsyncSelect(s, Handle, WM_SOCK, FD_READ);
//接收端SockAddrIn设定
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(UDPPORT); label3.Caption := '端口:' + inttostr(UDPPORT);end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(s);end;procedure TForm1.Button1Click(Sender: TObject);
begin
senddata(Edit1.text);end;end.
多谢了!
另,局域网中后发先至可以忽略!(个人观点)
用BufferUdp可以实现广播和组播