网上Delphi的Socket服务器优良代码,实在少见,索性写个简化的异步Socket服务器,虽然代码较少,但却该有的都有了,使用的是异步选择WSAAsyncSelect,减少了编写线程的繁琐。可能会问,性能如何?当然使用窗体消息通知,占用的是主线程,侦听、发送、多个客户端的接收都一个线程,大量数据时,性能当然是差强人意的,编写这个代码目的也不在于此。但是在实际的项目中,大数据量的情况也不多,以下是代码:(Delphi7编译)

{
最简化的消息异步Socket 异步选择WSAAsyncSelect, 没有64的限制
} program SocketDemo; {$APPTYPE CONSOLE} uses Windows, WinSock; const
ListenPort : Word = ;
BufferSize : DWORD = ; type
TConn = ^TConnData;
TConnData = record
FSocket: TSocket;
FAddrIn: TSockAddr;
Buffer : PChar;
BufLen : Integer;
end; procedure DoSocketData(Conn: TConn);
var S: string;
begin
Writeln(Conn.Buffer);
//这里插入业务处理代码
S:= 'Server echo';
send(Conn.FSocket, PChar(S)^, Length(S), );
end; //--------- 以下不要修改 -----------
const
wcName : PChar = 'THrWndClass';
WM_SOCKET = {WM_USER}$ + ; // 自定义消息 var
AddrInLen: Integer = SizeOf(TSockAddr); var FConns: array of TConn; function GetFreeConn: Integer;
var i: Integer;
begin
Result:= -;
for i:= to High(FConns) do
if FConns[i]=nil then begin
Result:= i; Break;
end;
if Result< then begin
Result:= Length(FConns); SetLength(FConns, Result+);
end;
FConns[Result]:= New(TConn);
GetMem(FConns[Result].Buffer, BufferSize+);
FConns[Result].BufLen:= BufferSize;
end; function GetCltConn(S: TSocket): Integer;
var i: Integer;
begin
for i:= to High(FConns) do
if Assigned(FConns[i]) and (FConns[i].FSocket=S) then begin
Result:= i; Break;
end;
end; procedure FreeConn(S: TSocket);
var id: Integer;
var Conn: TConn;
begin
id:= GetCltConn(S);
Conn:= FConns[id];
if not Assigned(Conn) then Exit;
FreeMem(Conn.Buffer);
CloseSocket(Conn.FSocket);
Dispose(Conn);
FConns[id]:= nil;
end; function WndProc(wnd, msg, sock, wm: DWORD): Integer; stdcall;
var id, AddrLen: Integer;
begin
Result:= DefWindowProc(wnd, msg, sock, wm);
if (msg<>WM_SOCKET) or (wm=) then Exit;
case LoWord(wm) of
FD_ACCEPT:
begin
id:= GetFreeConn;
with FConns[id]^ do begin
FSocket:= Accept(sock, @FAddrIn, @AddrInLen);
WSAAsyncSelect(FSocket, wnd, WM_SOCKET, FD_READ or FD_CLOSE);
end;
end;
FD_READ:
begin
id:= GetCltConn(sock);
with FConns[id]^ do begin
BufLen:= Recv(sock, Buffer^, BufferSize, );
if (BufLen<) or (BufLen>Buflen) then FreeConn(sock) else
begin
Buffer[BufLen]:= #;
try DoSocketData(FConns[id]) except end;
end;
end;
end;
FD_CLOSE: FreeConn(sock);
end;
end; function MakeWndHandle(WndProc: Pointer; wcName: PChar): HWND;
var wc: TWndClass;
begin
FillChar(wc, SizeOf(wc), );
wc.lpfnWndProc := WndProc;
wc.hInstance := HInstance;
wc.lpszClassName:= wcName;
Windows.RegisterClass(wc);
Result:= CreateWindow(wcName,'HrWnd',,,,,,,,HInstance,nil);
end; function SrvListen(Port: Word): Boolean;
var Wnd: HWND; S: TSocket; Addr: TSockAddrIn; WSAData: TWSAData;
begin
WSAStartup($, WSAData);
Addr.sin_family := AF_INET;
Addr.sin_port := Swap(Port);
Addr.sin_addr.S_addr := ;
S:= Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
Bind(S, Addr, AddrInLen); Wnd:= MakeWndHandle(@WndProc, wcName);
WSAAsyncSelect(S, Wnd, WM_SOCKET, FD_ACCEPT or FD_CLOSE);
//Writeln(SysErrorMessage(WSAGetLastError()), ' Wnd: ', Wnd);
Listen(S, );
end; procedure SysFina;
begin
Windows.UnregisterClass(wcName, HInstance);
WSACleanup;
end; procedure Stay;
var msg: TMsg;
begin
while GetMessage(msg, , , ) do begin
TranslateMessage(msg);
DispatchMessage (msg);
end;
PostQuitMessage();
end; begin
//if InitProc <> nil then TProcedure(InitProc);
SrvListen(ListenPort);
Stay;
SysFina;
Halt();
end.

Delphi最简化异步选择TCP服务器的更多相关文章

  1. 网络IO模型-异步选择模型(Delphi版)

    其实关于这个模型,网络上也有一个案例说明 老陈使用了微软公司的新式信箱.这种信箱非常先进,一旦信箱里有新的信件,盖茨就会给老陈打电话:喂,大爷,你有新的信件了!从此,老陈再也不必频繁上下楼检查信箱了, ...

  2. Swoole学习(七)Swoole之异步TCP服务器的创建

    环境:Centos6.4,PHP环境:PHP7 <?php //创建TCP服务器 /** * $host 是swoole需要监听的ip,如果要监听本地,不对外服务,那么就是127.0.0.1;如 ...

  3. 【Python】使用socketserver建立一个异步TCP服务器

    概述 这篇文章是讲解如何使用socketserver建立一个异步TCP服务器,其中Python版本为3.5.1. socketserver主要的类 socketserver模块中的类主要有以下几个:1 ...

  4. 06.swoole学习笔记--异步tcp服务器

    <?php //创建tcp服务器 $host='0.0.0.0'; $port=; $serv=new swoole_server($host,$port); //设置异步进程工作数 $serv ...

  5. php的异步非阻塞swoole模块使用(一)实现简易tcp服务器--服务端

    绑定tcp服务器的地址 $swserver = new swoole_server("127.0.0.1",9501); 设置tcp服务器装机容量(太危言耸听了-其实就是设置属性) ...

  6. 使用.net core在Ubuntu构建一个TCP服务器

    介绍和背景 TCP编程是网络编程领域最有趣的部分之一.在Ubuntu环境中,我喜欢使用.NET Core进行TCP编程,并使用本机Ubuntu脚本与TCP服务器进行通信.以前,我在.NET框架本身写了 ...

  7. 使用CBrother做TCP服务器与C++客户端通信

    使用CBrother脚本做TCP服务器与C++客户端通信 工作中总是会遇到一些对于服务器压力不是特别大,但是代码量比较多,用C++写起来很不方便.对于这种需求,我选择用CBrother脚本做服务器,之 ...

  8. LwIP应用开发笔记之五:LwIP无操作系统TCP服务器

    前面我们实现了UDP服务器及客户端以及基于其上的TFTP应用服务器.接下来我们将实现同样广泛应用的TCP协议各类应用. 1.TCP简述 TCP(Transmission Control Protoco ...

  9. PHP写的异步高并发服务器,基于libevent

    PHP写的异步高并发服务器,基于libevent 博客分类: PHP PHPFPSocketLinuxQQ  本文章于2013年11月修改. swoole已使用C重写作为PHP扩展来运行.项目地址:h ...

随机推荐

  1. bzoj 1898

    1898: [Zjoi2005]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1197  Solved: 661[Submit][S ...

  2. 【135】NoteExpress使用中的问题

    NoteExpress主要是用来管理文献,然后可以方便管理,方便插入,各种方便吧! 关于NoteExpress的下载可以直接搜索进入官网下载,为了不用破解之类的,可以选择大学版的! 引文显示上标!ht ...

  3. yield示例分析

    yield示例分析 public class TestYield { private static final Object lock = new Object(); public static vo ...

  4. hdu4604 Deque(最长上升子序列变形)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4604 题意:一个含有n个数栈,每次取出一个数,可以把这个数放在deque(双向队列)首部,放在尾部,或 ...

  5. 【WIP】外汇与证券交易29个技术指标

    创建: 2017/05/16   更新: 2017/05/30 更新: 2017/10/14 标题加上[WIP],增加创建时间  指标名称  函数原型(prototype)  参考与分析 (refer ...

  6. CodeForces E. Goods transportation【最大流+dp最小割】

    妙啊 首先暴力建图跑最大流非常简单,s向每个i连流量为p[i]的边,每个i向t连流量为s[i]的边,每个i向j连流量为c的边(i<j),但是会又T又M 考虑最大流=最小割 然后dp求最小割,设f ...

  7. bzoj 3624: [Apio2008]免费道路【生成树+贪心】

    先把水泥路建生成树,然后加鹅卵石路,这里加的鹅卵石路是一定要用的(连接各个联通块),然后初始化并查集,先把必需的鹅卵石路加进去,然后随便加鹅卵石路直到k条,然后加水泥路即可. 注意判断无解 #incl ...

  8. UVA1437 String painter

    传送门 我们先考虑从一个空白串变成\(B\),这样的话用区间dp,区间dp,设\(f[l][r]\)表示区间\((l,r)\)的最小次数,当\(l==r\)时为\(1\),当\(s[l]==s[r]\ ...

  9. input type="file"文件上传到后台读取

    html页面(表单采用bootStrap) js部分: //更换头像时把上传的图片post方式到控制器 <script type="text/javascript"> ...

  10. jQuery html操作

    jQuery 拥有可操作 HTML 元素和属性的强大方法. jQuery DOM 操作 DOM = Document Object Model(文档对象模型) jQuery 中非常重要的部分,就是操作 ...