新
新手101010
Unregistered / Unconfirmed
GUEST, unregistred user!
我现在在学socket,但不知道怎么用消息来处发事件,下面是代码
Server
const
MAXSOCKET = 128;
WM_Sock = WM_USER + 82;
type
TDataRec = record
IP: String[15];
NickName: String[10];
Data: PChar;
Len: Word;
end;
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
public
{ Public declarations }
Port: Integer;
ConnectCount: integer;
WSData: WSAData;
ServerAddr: TSockAddrIn;
ClientAddr: array[0..MAXSOCKET - 1] of TSockAddrIn;
ServerState: Boolean;
DataRec: TDataRec;
AcceptSocket: array[0..MAXSOCKET - 1] of TSocket;
procedure DisposeMsg(const Msg: TMessage);
procedure WndProc(var Msg: TMessage); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
WSAStartup(2, WSData);
ConnectCount := 0;
Port := 0;
for i := 0 to MAXSOCKET - 1 do
begin
AcceptSocket := 0;
end;
ServerState := False;
StatusBar1.Panels[0].Text := '服务器状态:关闭';
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
WSACleanup();
end;
procedure TForm1.WndProc(var Msg: TMessage);
begin
if (Msg.Msg>=WM_SOCK) and (Msg.Msg<=WM_SOCK+128) then
DisposeMsg(Msg);
inherited wndproc(Msg);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Port := StrToInt(Edit1.Text);
AcceptSocket[0] := Socket(AF_INET,SOCK_STREAM, 0);
if AcceptSocket[0] = 0 then
begin
Memo1.Lines.Add('Occur error when create a socket.');
Memo1.Lines.Add('Eror code:' + IntToStr(WSAGetLastError()));
Exit;
end;
ServerAddr.sin_family := AF_INET;
ServerAddr.sin_port := htonl(Port);
if Bind(AcceptSocket[0], ServerAddr, SizeOf(TSockAddrIn)) <> 0 then
begin
Memo1.Lines.Add('Occur error when bind a port to socket.');
Memo1.Lines.Add('Eror code:' + IntToStr(WSAGetLastError()));
Exit;
end;
if Listen(AcceptSocket[0], 1) <> 0 then
begin
Memo1.Lines.Add('Can''t Listen from port.');
Memo1.Lines.Add('Eror code:' + IntToStr(WSAGetLastError()));
Exit;
end;
WSAAsyncSelect(AcceptSocket[0], Handle, WM_Sock, FD_READ OR FD_ACCEPT OR FD_CLOSE);
ServerState := True;
StatusBar1.Panels[0].Text := '服务器状态:监听';
Timer1.Enabled := True;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to MAXSOCKET - 1 do
begin
CloseSocket(AcceptSocket);
end;
StatusBar1.Panels[0].Text := '服务器状态:关闭';
Timer1.Enabled := False;
StatusBar1.Panels[1].Text := '';
end;
procedure TForm1.DisposeMsg(const Msg: TMessage);
var
Event: Word;
len, i, index: integer;
begin
index := Msg.Msg - WM_SOCK;
Event := WSAGetSelectEvent(Msg.LParam);
len := Sizeof(TSockAddrIn);
case Event of
FD_READ:
begin
recv(AcceptSocket[index], DataRec, Sizeof(TDataRec), 0);
Memo1.Lines.Add('[' + TimeToStr(Now) + ']' + DataRec.NickName + ' : ' + StrPas(DataRec.Data));
end;
FD_ACCEPT:
begin
for i := 0 to MAXSOCKet - 1 do
begin
if AcceptSocket = 0 then
begin
AcceptSocket := Accept(AcceptSocket[0], @ClientAddr, @len);
WSAAsyncSelect(AcceptSocket, Handle, WM_SOCK + I + 1, FD_READ or FD_CLOSE);
Memo1.Lines.Add(inet_ntoa(ClientAddr.sin_addr) + ' connect server');
Inc(ConnectCount);
Break;
end;
end;
end;
FD_CLOSE:
begin
WSAAsyncSelect(AcceptSocket[index], Handle, 0, 0);
CloseSocket(AcceptSocket[index]);
Memo1.Lines.Add(inet_ntoa(ClientAddr[Index].sin_addr) + ' disconnected');
Dec(ConnectCount);
end;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
StatusBar1.Panels[1].Text := 'ConnectCount:' + IntToStr(ConnectCount);
end;
Client
const
WM_SOCK = WM_USER + 82;
type
TDataRec = record
IP: String[15];
NickName: String[10];
Data: PChar;
Len: Word;
end;
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
public
{ Public declarations }
WSData: WSAData;
DataRec: TDataRec;
ServerAdd: TSockAddrIn;
S: TSocket;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
WSAStartup(2, WSData);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(s);
WSACleanup();
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ServerAdd.sin_family := AF_INET;
ServerAdd.sin_addr.S_addr := inet_addr(Pchar(Edit1.Text));
ServerAdd.sin_port := htons(StrToInt(Edit2.Text));
s := Socket(AF_INET, SOCK_STREAM, 0);
if s = 0 then
begin
ShowMessage('Can''t create a socket.');
Exit;
end;
if connect(s, ServerAdd, SizeOf(ServerAdd)) <> 0 then
begin
WSAAsyncSelect(s, Handle , WM_SOCK, FD_READ or FD_CLOSE);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
CloseSocket(s);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if Edit3.Text <> '' then
begin
DataRec.Data := Pchar(Edit3.Text);
DataRec.NickName := Edit4.Text;
send(s, DataRec, SizeOf(TDataRec), 0);
end;
end;
以上是我的代码,由于是初学,有不好的地方可指出,谢谢
Server
const
MAXSOCKET = 128;
WM_Sock = WM_USER + 82;
type
TDataRec = record
IP: String[15];
NickName: String[10];
Data: PChar;
Len: Word;
end;
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
public
{ Public declarations }
Port: Integer;
ConnectCount: integer;
WSData: WSAData;
ServerAddr: TSockAddrIn;
ClientAddr: array[0..MAXSOCKET - 1] of TSockAddrIn;
ServerState: Boolean;
DataRec: TDataRec;
AcceptSocket: array[0..MAXSOCKET - 1] of TSocket;
procedure DisposeMsg(const Msg: TMessage);
procedure WndProc(var Msg: TMessage); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
WSAStartup(2, WSData);
ConnectCount := 0;
Port := 0;
for i := 0 to MAXSOCKET - 1 do
begin
AcceptSocket := 0;
end;
ServerState := False;
StatusBar1.Panels[0].Text := '服务器状态:关闭';
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
WSACleanup();
end;
procedure TForm1.WndProc(var Msg: TMessage);
begin
if (Msg.Msg>=WM_SOCK) and (Msg.Msg<=WM_SOCK+128) then
DisposeMsg(Msg);
inherited wndproc(Msg);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Port := StrToInt(Edit1.Text);
AcceptSocket[0] := Socket(AF_INET,SOCK_STREAM, 0);
if AcceptSocket[0] = 0 then
begin
Memo1.Lines.Add('Occur error when create a socket.');
Memo1.Lines.Add('Eror code:' + IntToStr(WSAGetLastError()));
Exit;
end;
ServerAddr.sin_family := AF_INET;
ServerAddr.sin_port := htonl(Port);
if Bind(AcceptSocket[0], ServerAddr, SizeOf(TSockAddrIn)) <> 0 then
begin
Memo1.Lines.Add('Occur error when bind a port to socket.');
Memo1.Lines.Add('Eror code:' + IntToStr(WSAGetLastError()));
Exit;
end;
if Listen(AcceptSocket[0], 1) <> 0 then
begin
Memo1.Lines.Add('Can''t Listen from port.');
Memo1.Lines.Add('Eror code:' + IntToStr(WSAGetLastError()));
Exit;
end;
WSAAsyncSelect(AcceptSocket[0], Handle, WM_Sock, FD_READ OR FD_ACCEPT OR FD_CLOSE);
ServerState := True;
StatusBar1.Panels[0].Text := '服务器状态:监听';
Timer1.Enabled := True;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to MAXSOCKET - 1 do
begin
CloseSocket(AcceptSocket);
end;
StatusBar1.Panels[0].Text := '服务器状态:关闭';
Timer1.Enabled := False;
StatusBar1.Panels[1].Text := '';
end;
procedure TForm1.DisposeMsg(const Msg: TMessage);
var
Event: Word;
len, i, index: integer;
begin
index := Msg.Msg - WM_SOCK;
Event := WSAGetSelectEvent(Msg.LParam);
len := Sizeof(TSockAddrIn);
case Event of
FD_READ:
begin
recv(AcceptSocket[index], DataRec, Sizeof(TDataRec), 0);
Memo1.Lines.Add('[' + TimeToStr(Now) + ']' + DataRec.NickName + ' : ' + StrPas(DataRec.Data));
end;
FD_ACCEPT:
begin
for i := 0 to MAXSOCKet - 1 do
begin
if AcceptSocket = 0 then
begin
AcceptSocket := Accept(AcceptSocket[0], @ClientAddr, @len);
WSAAsyncSelect(AcceptSocket, Handle, WM_SOCK + I + 1, FD_READ or FD_CLOSE);
Memo1.Lines.Add(inet_ntoa(ClientAddr.sin_addr) + ' connect server');
Inc(ConnectCount);
Break;
end;
end;
end;
FD_CLOSE:
begin
WSAAsyncSelect(AcceptSocket[index], Handle, 0, 0);
CloseSocket(AcceptSocket[index]);
Memo1.Lines.Add(inet_ntoa(ClientAddr[Index].sin_addr) + ' disconnected');
Dec(ConnectCount);
end;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
StatusBar1.Panels[1].Text := 'ConnectCount:' + IntToStr(ConnectCount);
end;
Client
const
WM_SOCK = WM_USER + 82;
type
TDataRec = record
IP: String[15];
NickName: String[10];
Data: PChar;
Len: Word;
end;
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
public
{ Public declarations }
WSData: WSAData;
DataRec: TDataRec;
ServerAdd: TSockAddrIn;
S: TSocket;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
WSAStartup(2, WSData);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(s);
WSACleanup();
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ServerAdd.sin_family := AF_INET;
ServerAdd.sin_addr.S_addr := inet_addr(Pchar(Edit1.Text));
ServerAdd.sin_port := htons(StrToInt(Edit2.Text));
s := Socket(AF_INET, SOCK_STREAM, 0);
if s = 0 then
begin
ShowMessage('Can''t create a socket.');
Exit;
end;
if connect(s, ServerAdd, SizeOf(ServerAdd)) <> 0 then
begin
WSAAsyncSelect(s, Handle , WM_SOCK, FD_READ or FD_CLOSE);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
CloseSocket(s);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if Edit3.Text <> '' then
begin
DataRec.Data := Pchar(Edit3.Text);
DataRec.NickName := Edit4.Text;
send(s, DataRec, SizeOf(TDataRec), 0);
end;
end;
以上是我的代码,由于是初学,有不好的地方可指出,谢谢