阿
阿伟~
Unregistered / Unconfirmed
GUEST, unregistred user!
服务端测试代码:
var
gint_serSocket: Integer;
sock: TSocket;
WSAData: TWSAData;
function Tf_main.InitServerSocket: Boolean;
var
SockAddrIn: TSockAddrIn;
begin
Result := True;
if WSAStartUp($0101, WSAData) <> 0 then
begin
Memo1.Lines.Add('初始化WSA失败');
Result := False;
Exit;
end;
gint_serSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if gint_serSocket = INVALID_SOCKET then
begin
Memo1.Lines.Add('创建SOCKET失败');
Result := False;
Exit;
end;
SockAddrIn := InitSockAddrIn('', StrToInt(Trim(edt_port.Text)));
if bind(gint_serSocket, SockAddrIn, sizeof(SockAddrIn)) < 0 then
begin
closesocket(gint_serSocket);
Memo1.Lines.Add('SOCKET绑定失败');
Result := False;
end;
end;
function Tf_main.InitSockAddrIn(IP: string; Port: word): TSockAddrIn;
begin
Result.sin_family := PF_INET;
if IP <> '' then
Result.sin_addr.S_addr := inet_addr(pchar(IP))
else
Result.sin_addr.S_addr := INADDR_ANY;
Result.sin_port := htons(Port);
end;
procedure Tf_main.btn_listenClick(Sender: TObject);
begin
if InitServerSocket then
begin
if listen(gint_serSocket, 5) <> 0 then
begin
Memo1.Lines.Add('SOCKET监听失败');
Exit;
end;
end;
end;
procedure Tf_main.btn_sendClick(Sender: TObject);
var
s: string;
a: PChar;
begin
if Trim(edt_ml.Text) = '' then
begin
ShowMessage('请输入发送命令');
edt_ml.Clear;
edt_ml.SetFocus;
Exit;
end;
s := Trim(edt_ml.Text);
a := 'c';
{ if (send(gint_serSocket, a, 10, 0)) = SOCKET_ERROR then //Pointer(s)^
Memo1.Lines.Add('命令发送失败失败!');}
end;
procedure Tf_main.WMSocket(var Msg: TMessage);
var
str: string;
addr: TSockAddrIn;
addrlen: Integer;
a: array[0..23] of Char;
begin
case WSAGetSelectEvent(Msg.LParam) of
FD_ACCEPT:
begin
addrlen := sizeof(addr);
sock := accept(Msg.WParam, @addr, @addrlen);
if sock <> INVALID_SOCKET then
begin
WSAAsyncSelect(Msg.WParam, Handle, WM_SOCKET, FD_READ or FD_WRITE or FD_CLOSE);
{ a := 'RCT36';
if (send(sock, a, 10, 0)) = SOCKET_ERROR then //Pointer(s)^
Memo1.Lines.Add('命令发送失败失败!');}
end;
end;
FD_CLOSE:
closesocket(Msg.WParam);
FD_READ:
begin
{recv(Msg.WParam, str[1], 1024, 0);
Memo1.Lines.Add(str);}
;
end;
FD_WRITE: ;
end;
end;
procedure Tf_main.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(gint_serSocket);
end;
××××××××××××××××××××××××××××××××××××××××
客户端代码:
unit u_main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, BaseGrid, AdvGrid, StdCtrls, ComCtrls, WinSock, IniFiles;
const WM_SOCKETEVENT = WM_USER + $1001; // Socket事件响应的消息
type
TSocketMessage = record // Socket消息的结构定义
Msg: Cardinal;
Socket: TSocket;
SelectEvent: Word;
SelectError: Word;
Result: Longint;
end;
type
Tf_main = class(TForm)
Panel1: TPanel;
M_COOL: TAnimate;
btn_begin: TButton;
memo1: TMemo;
sg_jl: TAdvStringGrid;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure btn_beginClick(Sender: TObject);
function InitClientSocket: Boolean;
procedure WMSocketEvent(var M: TSocketMessage); message WM_SOCKETEVENT;
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormClose(Sender: TObject; var Action: TCloseAction); //自定义SOCK消息
private
{ Private declarations }
public
{ Public declarations }
end;
var
f_main: Tf_main;
implementation
{$R *.dfm}
uses pub, u_set;
var
gint_Tran: Integer = 0;
gint_port: Integer;
gstr_address, gstr_send: string;
gint_CltSock: TSocket; //客户端套接字
procedure Tf_main.FormCreate(Sender: TObject);
var
s: string;
MyIni: TIniFile;
begin
if FileExists(ExtractFilePath(Paramstr(0)) + 'Internet.ini') then
begin
try
MyIni := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'Internet.ini');
gstr_address := MyIni.ReadString('internet', 'IP', '');
gint_port := MyIni.ReadInteger('internet', 'port', 0);
finally
MyIni.Free;
end;
end;
s := '房号*10*日期*24*基价*10*其他费用*12*合计费用*14*';
title_sg_wy(sg_jl, s);
end;
procedure Tf_main.btn_beginClick(Sender: TObject);
var
SockAddrIn: TSockAddrIn;
begin
if not InitClientSocket then
begin
memo1.Lines.Text := '创建套接字失败';
Exit;
end;
SockAddrIn := InitSockAddrIn(gstr_address, gint_port);
WSAAsyncSelect(gint_CltSock, Handle, WM_SOCKETEVENT, FD_CONNECT);
memo1.Lines.Add('正在连接服务器' + gstr_address + '... ...');
WinSock.connect(gint_CltSock, SockAddrIn, SizeOf(TSockAddrIn));
end;
function Tf_main.InitClientSocket: Boolean;
begin
Result := True;
if InitWSA then
begin
gint_CltSock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if gint_CltSock = INVALID_SOCKET then
Result := False;
end
else
Result := False;
end;
procedure Tf_main.WMSocketEvent(var M: TSocketMessage);
var
Sock: TSocket;
str: string;
achr: Char;
begin
{
-----------------------------------------------------
WSAASyncSelect模型就是把一个窗口和套接字句柄建立起连接,
套接字的网络事件发生时时候,就会把某个消息发送到窗口,
然后可以在窗口的消息响应函数中处理数据的接收和发送。
----------------------------------------------------
}
Sock := M.Socket;
case M.SelectEvent of
FD_CONNECT:
if M.SelectError <> 0 then
begin
btn_begin.Enabled := True;
CloseSocket(M.Socket);
Memo1.Lines.Add('服务器忙,请稍后再试!');
end
else
begin
Memo1.Lines.Add('连接成功!');
btn_begin.Enabled := False;
achr := 'a';
if (send(Sock, achr, 2, 0)) = SOCKET_ERROR then
Memo1.Lines.Add('Error!');
WSAAsyncSelect(M.Socket, Handle, WM_SOCKETEVENT, FD_READ or FD_WRITE or FD_CLOSE);
end;
FD_READ:
begin
if Timer1.Enabled = True then
Timer1.Enabled := False;
recv(Sock, str[1], 20, 0);
if Pos('RCT36', str) > 0 then { TODO : 握手信号 }
begin
achr := Chr(6);
if (send(Sock, achr, 2, 0)) = SOCKET_ERROR then
Memo1.Lines.Add('握手信号回复失败!')
else
begin
Memo1.Lines.Add('握手信号回复!');
Timer1.Enabled := True;
end;
end;
end;
FD_WRITE:
;
FD_CLOSE:
begin
Memo1.Lines.Add('服务器已经断开连接');
shutdown(gint_CltSock, SD_BOTH);
CloseSocket(gint_CltSock);
end;
end;
end;
procedure Tf_main.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
VK_F12:
begin
f_set := Tf_set.Create(Self);
f_set.ShowModal;
end;
end;
end;
procedure Tf_main.FormClose(Sender: TObject; var Action: TCloseAction);
begin
shutdown(gint_CltSock, SD_BOTH);
CloseSocket(gint_CltSock);
end;
end.
为什么我在客户段 achr := 'a';
if (send(Sock, achr, 2, 0)) = SOCKET_ERROR then
Memo1.Lines.Add('Error!');
WSAAsyncSelect(M.Socket, Handle, WM_SOCKETEVENT, FD_READ or FD_WRITE or FD_CLOSE);发送后,服务端始终没有收到消息呢?发送也是成功得。请各位达人帮我看看,谢谢
var
gint_serSocket: Integer;
sock: TSocket;
WSAData: TWSAData;
function Tf_main.InitServerSocket: Boolean;
var
SockAddrIn: TSockAddrIn;
begin
Result := True;
if WSAStartUp($0101, WSAData) <> 0 then
begin
Memo1.Lines.Add('初始化WSA失败');
Result := False;
Exit;
end;
gint_serSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if gint_serSocket = INVALID_SOCKET then
begin
Memo1.Lines.Add('创建SOCKET失败');
Result := False;
Exit;
end;
SockAddrIn := InitSockAddrIn('', StrToInt(Trim(edt_port.Text)));
if bind(gint_serSocket, SockAddrIn, sizeof(SockAddrIn)) < 0 then
begin
closesocket(gint_serSocket);
Memo1.Lines.Add('SOCKET绑定失败');
Result := False;
end;
end;
function Tf_main.InitSockAddrIn(IP: string; Port: word): TSockAddrIn;
begin
Result.sin_family := PF_INET;
if IP <> '' then
Result.sin_addr.S_addr := inet_addr(pchar(IP))
else
Result.sin_addr.S_addr := INADDR_ANY;
Result.sin_port := htons(Port);
end;
procedure Tf_main.btn_listenClick(Sender: TObject);
begin
if InitServerSocket then
begin
if listen(gint_serSocket, 5) <> 0 then
begin
Memo1.Lines.Add('SOCKET监听失败');
Exit;
end;
end;
end;
procedure Tf_main.btn_sendClick(Sender: TObject);
var
s: string;
a: PChar;
begin
if Trim(edt_ml.Text) = '' then
begin
ShowMessage('请输入发送命令');
edt_ml.Clear;
edt_ml.SetFocus;
Exit;
end;
s := Trim(edt_ml.Text);
a := 'c';
{ if (send(gint_serSocket, a, 10, 0)) = SOCKET_ERROR then //Pointer(s)^
Memo1.Lines.Add('命令发送失败失败!');}
end;
procedure Tf_main.WMSocket(var Msg: TMessage);
var
str: string;
addr: TSockAddrIn;
addrlen: Integer;
a: array[0..23] of Char;
begin
case WSAGetSelectEvent(Msg.LParam) of
FD_ACCEPT:
begin
addrlen := sizeof(addr);
sock := accept(Msg.WParam, @addr, @addrlen);
if sock <> INVALID_SOCKET then
begin
WSAAsyncSelect(Msg.WParam, Handle, WM_SOCKET, FD_READ or FD_WRITE or FD_CLOSE);
{ a := 'RCT36';
if (send(sock, a, 10, 0)) = SOCKET_ERROR then //Pointer(s)^
Memo1.Lines.Add('命令发送失败失败!');}
end;
end;
FD_CLOSE:
closesocket(Msg.WParam);
FD_READ:
begin
{recv(Msg.WParam, str[1], 1024, 0);
Memo1.Lines.Add(str);}
;
end;
FD_WRITE: ;
end;
end;
procedure Tf_main.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(gint_serSocket);
end;
××××××××××××××××××××××××××××××××××××××××
客户端代码:
unit u_main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, BaseGrid, AdvGrid, StdCtrls, ComCtrls, WinSock, IniFiles;
const WM_SOCKETEVENT = WM_USER + $1001; // Socket事件响应的消息
type
TSocketMessage = record // Socket消息的结构定义
Msg: Cardinal;
Socket: TSocket;
SelectEvent: Word;
SelectError: Word;
Result: Longint;
end;
type
Tf_main = class(TForm)
Panel1: TPanel;
M_COOL: TAnimate;
btn_begin: TButton;
memo1: TMemo;
sg_jl: TAdvStringGrid;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure btn_beginClick(Sender: TObject);
function InitClientSocket: Boolean;
procedure WMSocketEvent(var M: TSocketMessage); message WM_SOCKETEVENT;
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormClose(Sender: TObject; var Action: TCloseAction); //自定义SOCK消息
private
{ Private declarations }
public
{ Public declarations }
end;
var
f_main: Tf_main;
implementation
{$R *.dfm}
uses pub, u_set;
var
gint_Tran: Integer = 0;
gint_port: Integer;
gstr_address, gstr_send: string;
gint_CltSock: TSocket; //客户端套接字
procedure Tf_main.FormCreate(Sender: TObject);
var
s: string;
MyIni: TIniFile;
begin
if FileExists(ExtractFilePath(Paramstr(0)) + 'Internet.ini') then
begin
try
MyIni := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'Internet.ini');
gstr_address := MyIni.ReadString('internet', 'IP', '');
gint_port := MyIni.ReadInteger('internet', 'port', 0);
finally
MyIni.Free;
end;
end;
s := '房号*10*日期*24*基价*10*其他费用*12*合计费用*14*';
title_sg_wy(sg_jl, s);
end;
procedure Tf_main.btn_beginClick(Sender: TObject);
var
SockAddrIn: TSockAddrIn;
begin
if not InitClientSocket then
begin
memo1.Lines.Text := '创建套接字失败';
Exit;
end;
SockAddrIn := InitSockAddrIn(gstr_address, gint_port);
WSAAsyncSelect(gint_CltSock, Handle, WM_SOCKETEVENT, FD_CONNECT);
memo1.Lines.Add('正在连接服务器' + gstr_address + '... ...');
WinSock.connect(gint_CltSock, SockAddrIn, SizeOf(TSockAddrIn));
end;
function Tf_main.InitClientSocket: Boolean;
begin
Result := True;
if InitWSA then
begin
gint_CltSock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if gint_CltSock = INVALID_SOCKET then
Result := False;
end
else
Result := False;
end;
procedure Tf_main.WMSocketEvent(var M: TSocketMessage);
var
Sock: TSocket;
str: string;
achr: Char;
begin
{
-----------------------------------------------------
WSAASyncSelect模型就是把一个窗口和套接字句柄建立起连接,
套接字的网络事件发生时时候,就会把某个消息发送到窗口,
然后可以在窗口的消息响应函数中处理数据的接收和发送。
----------------------------------------------------
}
Sock := M.Socket;
case M.SelectEvent of
FD_CONNECT:
if M.SelectError <> 0 then
begin
btn_begin.Enabled := True;
CloseSocket(M.Socket);
Memo1.Lines.Add('服务器忙,请稍后再试!');
end
else
begin
Memo1.Lines.Add('连接成功!');
btn_begin.Enabled := False;
achr := 'a';
if (send(Sock, achr, 2, 0)) = SOCKET_ERROR then
Memo1.Lines.Add('Error!');
WSAAsyncSelect(M.Socket, Handle, WM_SOCKETEVENT, FD_READ or FD_WRITE or FD_CLOSE);
end;
FD_READ:
begin
if Timer1.Enabled = True then
Timer1.Enabled := False;
recv(Sock, str[1], 20, 0);
if Pos('RCT36', str) > 0 then { TODO : 握手信号 }
begin
achr := Chr(6);
if (send(Sock, achr, 2, 0)) = SOCKET_ERROR then
Memo1.Lines.Add('握手信号回复失败!')
else
begin
Memo1.Lines.Add('握手信号回复!');
Timer1.Enabled := True;
end;
end;
end;
FD_WRITE:
;
FD_CLOSE:
begin
Memo1.Lines.Add('服务器已经断开连接');
shutdown(gint_CltSock, SD_BOTH);
CloseSocket(gint_CltSock);
end;
end;
end;
procedure Tf_main.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
VK_F12:
begin
f_set := Tf_set.Create(Self);
f_set.ShowModal;
end;
end;
end;
procedure Tf_main.FormClose(Sender: TObject; var Action: TCloseAction);
begin
shutdown(gint_CltSock, SD_BOTH);
CloseSocket(gint_CltSock);
end;
end.
为什么我在客户段 achr := 'a';
if (send(Sock, achr, 2, 0)) = SOCKET_ERROR then
Memo1.Lines.Add('Error!');
WSAAsyncSelect(M.Socket, Handle, WM_SOCKETEVENT, FD_READ or FD_WRITE or FD_CLOSE);发送后,服务端始终没有收到消息呢?发送也是成功得。请各位达人帮我看看,谢谢