ServerFrm.pas
上传用户:psxgmh
上传日期:2013-04-08
资源大小:15112k
文件大小:5k
源码类别:

Delphi/CppBuilder

开发平台:

Delphi

  1. unit ServerFrm;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  5.   StdCtrls, Buttons, ComCtrls, WinSock, ExtCtrls;
  6. type
  7.   TFrmMain = class(TForm)
  8.     StaBar: TStatusBar;
  9.     SaveDialog1: TSaveDialog;
  10.     Panel1: TPanel;
  11.     Label2: TLabel;
  12.     OtherPort: TEdit;
  13.     Panel2: TPanel;
  14.     btnListen: TBitBtn;
  15.     btnRecv: TBitBtn;
  16.     btnStop: TBitBtn;
  17.     btnExit: TBitBtn;
  18.     procedure btnExitClick(Sender: TObject);
  19.     procedure FormCreate(Sender: TObject);
  20.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  21.     procedure btnRecvClick(Sender: TObject);
  22.     procedure btnStopClick(Sender: TObject);
  23.     procedure btnListenClick(Sender: TObject);
  24.   private
  25.     { Private declarations }
  26.   public
  27.     { Public declarations }
  28.     StopTrans: Boolean; //是否停止传送开关
  29.     InTrans: Boolean; //表示是否正在接收文件
  30.     Server: TSocket; //定义服务器端Socket句柄
  31.     //自定义过程接收文件
  32.     procedure RecvFile(filename: string);
  33.   end;
  34. var
  35.   FrmMain: TFrmMain;
  36. const BlockLen = 1024 * 4;
  37. implementation
  38. {$R *.DFM}
  39. //当窗体创建时,启动winSock动态链接库
  40. procedure TFrmMain.FormCreate(Sender: TObject);
  41. var
  42.   aWSAData: TWSAData;
  43. begin
  44.   if WSAStartup($0101, aWSAData) <> 0 then
  45.     raise Exception.Create('不能启动WinSock动态链接库!');
  46.   MessageBox(Handle, aWSAData.szDescription, 'WinSock 态链接库版本', MB_OK);
  47. end;
  48. //关闭窗口
  49. procedure TFrmMain.btnExitClick(Sender: TObject);
  50. begin
  51.   Close;
  52. end;
  53. //窗口关闭时,检测是否正在接收文件
  54. procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
  55. begin
  56.   if InTrans then
  57.     if MessageBox(Handle, '正在接收文件,停止吗?', '提示', MB_YESNO) = IDNO then
  58.       abort;
  59.   //关闭Socket
  60.   if Server <> INVALID_SOCKET then
  61.     closesocket(Server);
  62.   //释放WinSock动态库创建的资源
  63.   if WSACleanup <> 0 then
  64.     MessageBox(Handle, '清除WinSock动态链接库错误!', '提示', MB_OK)
  65.   else MessageBox(Handle, '清除WinSock动态链接库成功!', '提示', MB_OK)
  66. end;
  67. //让服务器端的Socket开始监听
  68. procedure TFrmMain.btnListenClick(Sender: TObject);
  69. var
  70.   ca: SOCKADDR_IN;
  71. begin
  72.   //创建服务器端Socket
  73.   Server := Socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
  74.   if Server = INVALID_SOCKET then
  75.   begin
  76.     StaBar.SimpleText := '创建接收Socket错误!';
  77.     Exit;
  78.   end;
  79.   //绑定服务器端Socket
  80.   ca.sin_family := PF_INET;
  81.   ca.sin_port := htons(StrToInt(Trim(OtherPort.Text)));
  82.   ca.sin_addr.S_addr := INADDR_ANY;
  83.   if bind(Server, ca, sizeof(ca)) = SOCKET_ERROR then
  84.   begin
  85.     StaBar.SimpleText := '绑定接收端Socket错误!请更改接收端口!';
  86.     closesocket(Server);
  87.     Exit;
  88.   end
  89.   else
  90.     StaBar.SimpleText := '绑定接收端Socket成功!';
  91.   //开始监听
  92.   listen(Server, 5);
  93.   BtnListen.Enabled := False;
  94.   BtnStop.Enabled := True;
  95. end;
  96. //接收文件
  97. procedure TFrmMain.RecvFile(filename: string);
  98. var
  99.   Ftrans: file of Byte;
  100.   Recelen: Integer;
  101.   BlockBuf: array[0..BlockLen - 1] of Byte;
  102.   RecvSocket: TSocket;
  103.   ra: SOCKADDR_IN;
  104.   ra_len: Integer;
  105. begin
  106.   Ra_len := sizeof(Ra);
  107.   //等待连接的客户端Socket
  108.   RecvSocket := accept(Server, @ra, @ra_len);
  109.   //创建一个保存的文件
  110.   AssignFile(Ftrans, filename);
  111.   ReWrite(Ftrans);
  112.   //设置状态变量
  113.   StopTrans := False;
  114.   InTrans := True;
  115.   //接收数据
  116.   Recelen := recv(RecvSocket, BlockBuf, BlockLen, 0);
  117.   while (Recelen > 0) and (not StopTrans) do
  118.   begin
  119.     BlockWrite(Ftrans, BlockBuf[0], Recelen);
  120.     Application.ProcessMessages;
  121.     Recelen := recv(RecvSocket, BlockBuf, BlockLen, 0);
  122.       //当停止接收时,停止传输
  123.     if StopTrans then
  124.     begin
  125.       CloseFile(Ftrans);
  126.       closesocket(RecvSocket);
  127.       InTrans := False;
  128.       MessageBox(Handle, '停止传输!', '提示', MB_OK);
  129.       Exit;
  130.     end;
  131.   end;
  132.   //关闭文件,接收的Socket
  133.   CloseFile(Ftrans);
  134.   closesocket(RecvSocket);
  135.   InTrans := False;
  136.   if (Recelen = SOCKET_ERROR) then
  137.     MessageBox(Handle, '传输异常终止!', '提示', MB_OK)
  138.   else
  139.     MessageBox(Handle, '客户端已经关闭连接!文件可能已经传送完毕!', '提示', MB_OK);
  140. end;
  141. //开始接收文件
  142. procedure TFrmMain.btnRecvClick(Sender: TObject);
  143. begin
  144.   if (Server = INVALID_SOCKET) then
  145.   begin
  146.     MessageBox(Handle, '还没有进行监听,请先进行监听!', '提示', MB_OK);
  147.     Exit;
  148.   end;
  149.   if SaveDialog1.Execute then
  150.     RecvFile(saveDialog1.FileName);
  151. end;
  152. //停止接收文件
  153. procedure TFrmMain.btnStopClick(Sender: TObject);
  154. begin
  155.   StopTrans := True;
  156.   if Server <> INVALID_SOCKET then closesocket(Server);
  157.         //此处需说明;
  158.   Server := INVALID_SOCKET;
  159.   BtnStop.Enabled := False;
  160.   BtnListen.Enabled := True;
  161. end;
  162. end.