没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|其它|编辑:郝浩|2005-02-25 09:49:00.000|阅读 1834 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
本篇将通过一次Socket通信操作来对ServerSocket和ClientSocket这两个控件的源码进行一次阅读,希望能理出一个脉络来,以供大家参考。其实说得确切一点,应该是对Scktcomp这个单元进行解读,但由于这个单元的代码太多了,所以不可能面面俱到,我试图以非阻塞式的通信来一步步说明它们是怎么样封装WinSock的API的,至于阻塞式的,在ServerSocket和ClientSocket并不常用,所以这一篇就不打算说了,可能源码中会有一些忽略掉,以后有时间来补一篇阻塞式的阅读吧。虽然现在Delphi已经用Indy控件替换了SS和CS等网络控件,但毕竟这两个控件是对Socket函数进行封装,学习它怎么样封装也好吧。
在这之前,须对WinSock有一个大概的了解,但也仅止大概,对Socket编程有一个总体的掌握行了,毕竟那不是我的能力所及。想要系统一点的学习Socket,可以去网上下WinSocket的中文文档以及参考MSDN。
在开始使用WinSock的Api的时候,必须加载WinSock Dll的相应版本,这时用到的函数是:
int WSAStartup (
WORD wVersionRequested,
LPWSADATA lpWSAData
);
wVersionRequested指定用到的WinSock的最低版本,高字节指定副版本,低字节指定主版本,关于WinSock的版本,详见MSDN。
lpWSAData结构类型,系统把加载进去的版本信息添加到这个结构中。
该函数成功返回0,不成功则返回几个错误代码之一
这个函数和WSACleanup对应,查看MSDN
从MSDN列出一个例子:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
调用上面的函数之后,就可以用下面的函数来创建一个Socket了,Socket是WinSock定义的数据类型(整数),相当于句柄,用于标识系统中的每一个Socket连接
SOCKET socket (
int af,
int type,
int protocol
);
Af协议标志,Internet协议族的标志是PINET。
Type 协议类型志,SOCISTREAM表明是面向连接的字节流类型,SOCIDGRAM表明是面向无连接的数据报类型。
Protocol Socket采用的协议类型,如果采用IPPROTO_TCP常数就是采用了TCP协议。
如果调用失败,会返回INVALID_SOCKET值,正常的Socket取值范围是1~INVALID_SOCKET-1;
下面的函数将Socket与特定的主机进行绑定:
int bind (
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
S就是一个Socket,由Socket()函数返回得到的。
Name是sockaddr结构的变量
Namelen是Name结构的长度。
如果函数调用成功,将返回0,如果不成功,将返回SOCKET_ERROR,可以从WSAGetLastError.函数获得错误代码。
现在说sockaddr这个结构,在Winsock中其实有两个功能相似的结构,它们是:
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
这两个结构在Delphi中被声明为一个变体记录,这两个指定通信的本地主机地址,本地协议端口,另外还有通信过程中使用的协议类型。
其中:sin_family规定了哪个协议用来实现套按字连接。WinSock必须设置常数AF_INET
sin_port;:WinSock应用程序使用的端口号
sin_addr:这个是32位IP地址
sin_zero[8];这个保留,没有使用。
Server端必须调用Bind()函数,设计时可以将地址设定为INADDR_ANY,这样WinSock会自动加入机器正确的地址.
以下是客户端向服务端连接时调用的函数
int connect (
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
函数里的参数和bind()一个,不多说了,函数成功时返回0,否则返回SOCKET_ERROR。
服务端在Bind之后,调用下面函数进行监视。
int listen (
SOCKET s,
int backlog
);
其中backlog是可以建立的最大连接数,如果值设为SOMAXCONN,将由Socket的服务提供商设定一个合理的值,这个值不确定。
函数成功时返回0,否则返回SOCKET_ERROR。
当客户端连接服务端,服务端调用下面函数接收客户的请求,并向客户机发送应答信息
SOCKET accept (
SOCKET s,
struct sockaddr FAR* addr,
int FAR* addrlen
);
其中中addr是用来保存客户机地址信息的指针
Addrlen是addr的长度一般是Sizeof(addr)
如果函数成功,则返回一个Socket,这个Socket才是与客户实际通信的套接字,原来的那个Socket继续监视其他客户端的连接
以下几个是用个服务机和客户机通信的函数,
int send (SOCKET s,const char FAR * buf, int len,int flags );
在面向连接的情况下发送数据
int recv (SOCKET s, char FAR* buf, int len, int flags );
在面向连接的情况下接收数据
另外还有sendto和recvfrom用于无连接情况,具体查MSDN
其中Buf是发送或接收的缓冲区,Len是缓冲区的大小,Flags是网络呼叫产生方式标志,值可以为0,MSG_DONTROUTE或
MSG_OOB用途具体看MSDN。
通信完毕后,需要关闭Socket,函数声明如下:
int closesocket (
SOCKET s
);
在程序的最后,需要调用下面的函数,结束WinSock DLL
int WSACleanup (void);
函数成功时返回0,否则返回SOCKET_ERROR。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号