★★★★★★★★超简单的Socket消息★★★★★★★★★★★★★★ ( 积分: 50 )

  • 主题发起人 主题发起人 新手101010
  • 开始时间 开始时间

新手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;


以上是我的代码,由于是初学,有不好的地方可指出,谢谢
 
我现在在学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;


以上是我的代码,由于是初学,有不好的地方可指出,谢谢
 
没有人会吗?
 
代码里面不是已经处理了吗!
 
可是那个收不到消息
 
自己查一下帮助看看吧。
When one of the nominated network events occurs on the specified socket s, the application window hWnd receives message wMsg. The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in Winsock2
 
if connect(s, ServerAdd, SizeOf(ServerAdd)) <> 0 then //这里的问题,应该是connect=0
begin
WSAAsyncSelect(s, Handle , WM_SOCK, FD_READ or FD_CLOSE);
end;
connect函数的帮助:

Return Values
If no error occurs, connect returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
 
我改过来了,可还是不行呀,Help
 
没看出哪有毛病
问题出在哪了,server收不到消息?

AcceptSocket: array[0..MAXSOCKET - 1] of TSocket这个东西不要最好,
msg.wparam就是accept来的socket
 
我认为是消息的事,我对它一点也不明白是怎么收到每一个连接用户的消息的
 
介意参考DELPHI自带的chat程序,里面的东西是基础;
你只要再扩展一下就好了;
 
后退
顶部