Socket网络编程及其实现(图文)

论文导读:网络应用程序是通过网络使用通信协议实现进程间的通信,TCP/IP就是网络上常用的协议之一,在进行网络应用程序设计时,TCP/IP协议的核心内容被封装在操作系统中。因此,可以说设计网络应用程序就是利用网络编程接口(API)进行程序设计的过程。在Windows环境下的网络应用程序编程接口叫WindowsSockets,即套接口。

关键词:套接口,网络编程,TCP/IP协议

1 引言

网络应用程序是通过网络使用通信协议实现进程间的通信,TCP/IP就是网络上常用的协议之一,在进行网络应用程序设计时,TCP/IP协议的核心内容被封装在操作系统中。网络应用程序要使用TCP/IP协议来实现自己的功能,只能通过由系统提供给用户的TCP/IP协议编程接口来实现[1]。因此,可以说设计网络应用程序就是利用网络编程接口(API)进行程序设计的过程。在Windows环境下的网络应用程序编程接口叫Windows Sockets,即套接口。

2 套接口

2.1 套接口的概念

WindowsSockets API 依靠套接口Socket进行通信。套接口可看成是两个网络应用程序进行通信时,各自通信连接中的一个端点。通信时,其中的一个网路应用程序将要传输的一段信息写入它所在主机的Socket中,该Socket通过网络接口卡(NIC)的传输介质将这段信息发送到另一台主机的Socket中,使这段信息能传送到其它程序中,如图1所示。[1]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rgr1fECb-1661290235914)(http://www.lunwenf.com/picture/pic20110423/286029.jpg)]

当主机A上的网络应用程序A要发送数据时,通过调用数据发送函数首先将要发送的一段信息写入Socket中,Socket中的内容通过主机A的网络管理软件由主机A的网络接口卡发送到主机B,主机B的网络接口卡接收到这段信息后,再传给主机B的网络管理软件,网络管理软件将这段信息保存在主机B的Socket中,然后程序B才能在Socket中读取并使用这段信息。由此看来,Socket的本质是通信过程中所要使用的一些缓冲区及一些相关的数据结构。

2.2 套接口的分类

为了满足不同的通信程序对通信质量和性能的要求,一般的网络系统提供了三种不同类型的套接口,以供用户在设计网络应用程序时根据不同的要求来选择。免费论文。这三种套接口分别是:

(1)流式套接口(SOCK_STREAM),它提供了一种可靠的、面向连接的双向数据传输服务,实现数据无差错、无重复地发送。流失套接口内设流量控制,被传输的数据看作是无记录边界的字节流。在TCP/IP协议族中,使用TCP协议来实现字节流的传输,当用户想要发送大批量的数据或者对数据的传输有较高的要求时,使用流式套接口。

(2)数据报套接口(SOCK_DGRAM),它提供了一种无连接、不可靠的双向数据传输服务。免费论文。数据包以独立的包形式被发送,并保留了记录边界,不提供可靠性保证。数据在传输过程中可能会丢失或重复,并且不能保证在接收端数据按发送顺序接收。免费论文。在TCP/IP协议族中,使用UDP协议来实现数据报套接口。在同一台计算机上或负载较轻的LAN上,因为出现差错的可能性较小,所以可以使用数据报套接口进行数据传输,这样通信的质量可以得到保证,并且通信的效率较高。

(3)原始套接口(SOCK_RAW),该套接口允许对较低层协议(如IP或ICMP)进行直接访问,常用于检验新的网络协议实现,也可用于测试新配置或安装的网络设备。

3 Socket编程基础

3.1 Socket工作模式

Socket以客户/服务器模式工作。Socket服务器程序通常事先已经启动,并在一个众所周知的端口监听对服务的请求。Socket客户应用程序需要某种服务时,便向提供服务的Socket服务器发出请求,服务器接收到请求后,就响应客户提出的请求[2]。

3.2 基本套接字的系统调用

应用程序常用的函数列举如下,

WSAStarup():检查系统中是否有WindowsSockets的实现库

Socket():创建一个Socket

Bind():为创建的Socket指定通信对象

Connect():请求连接

Listen():等待连接状态

Accept():接收连接请求

Send()/Recv():发送接收数据(TCP)

Sendto()/Recvfrom():发送接收数据(UDP)

CloseSocket():关闭指定的Socket

WSACleanup():释放为应用程序或DLL分配的任何资源

3.3用于无连接协议(如UDP)的Socket系统调用流程框图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0W3jBO8L-1661290235915)(http://www.lunwenf.com/picture/pic20110423/286030.jpg)]

3.4 用于面向连接协议(如TCP)的Socket系统调用流程框图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uVgmMtOF-1661290235916)(http://www.lunwenf.com/picture/pic20110423/286031.jpg)]

4 编程实例

本实例使用了Visual C++6.0下的控制台程序,该程序中的通信协议使用的是面向连接的TCP协议(SOCK_STREAM)[3]。服务器端的IP地址使用系统指定的IP地址,端口号在程序中指定为6000。

4.1 服务器端的实现

建立一个空的基于控制台的应用程序 TCPserver,引入头文件:WINSOCK2.H,在Project—>settings—>ink—>object/libarymodules 下引入:ws2_32.lib库

实现代码如下,

#include #include

int main(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);if (err!=0){return 0;}if (LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1){WSACleanup();return 0;}

//检查系统中是否有Windows Sockets的实现库,如果没有则释放为应用程序或DLL分配的任何资源

SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);

//创建套接口SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

//htonl()函数把一个四字节主机字节顺序的数转换为网络字节顺序的数addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);

//htons()函数把一个双字节主机字节顺序的数转换为网络字节顺序数

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

//把套接口与指定的主机ip地址和端口号联系起来listen(sockSrv,5);

//进入监听状态,最多同时可以接受5个连接请求SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);

while (TRUE){SOCKET sockTemp=accept(sockSrv,(SOCKADDR*)&addrClient,&len);

//创建一个临时套接口,与其中一个客户端建立连接

char sendbuff[1024];sprintf(sendbuff,‘Welcome to zhangjie’);

//将字符串格式化到buff中去send(sockTemp,sendbuff,strlen(sendbuff)+1,0);

//向客户端发送数据

char recvBuff[1024];recv(sockTemp,recvBuff,strlen(recvBuff)+1,0);

//接收客户端发送的数据printf('%s ',recvBuff);

closesocket(sockTemp);

//关闭套接口

}return 0;}

4.2 客户端的实现

建立一个空的基于控制台的应用程序TCPClient,引入头文件:WINSOCK2.H,在Project—>settings—>ink—>object/libarymodules 下引入:ws2_32.lib库

实现代码如下,

#include #include

int main(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);if (err!=0){return 0;}if (LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1){WSACleanup();return 0;}

//检查系统中是否有Windows Sockets的实现库,如果没有则释放为应用程序或DLL分配的任何资源

SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrClient;addrClient.sin_addr.S_un.S_addr=inet_addr(‘127.0.0.1’);

//点分十进制转化成ULong类型addrClient.sin_family=AF_INET;addrClient.sin_port=htons(6000);

//转化成网络字节序connect(sockClient,(SOCKADDR *)&addrClient,sizeof(SOCKADDR));

//请求与服务器建立连接char recvBuff[1024];

recv(sockClient,recvBuff,1024,0);printf('%s ',recvBuff);

send(sockClient,‘I am zhangjie’,strlen('I am zhangjie ')+1,0);

closesocket(sockClient);WSACleanup();

//通信结束后释放资源return 0;}

5 小结

本文介绍了套接口的基本概念和实现套接口编程的基础,并给出了一个在VC平台下实现的基于TCP的客户/服务器通信实例,体现了套接口编程的灵活性。

6 参考文献

[1]任泰明.TCP/IP协议与网络编程[M].第1版.西安:西安电子科技大学出版社.2004;94-139

[2]邹月,陈建兵.Socket的网络编程研究与实现[J].电脑编程技巧与维护.2008.10-12

[3]谭桂华,魏亮.Visual C#高级编程范例[M].第1版.北京:清华大学出版社.2004;202-235

5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值