Windows网络编程:阻塞模式下的Socket编程
Posted Herbert_Zero
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows网络编程:阻塞模式下的Socket编程相关的知识,希望对你有一定的参考价值。
一、Socket的含义
Windows Socket是从UNIX Socket继承发展而来,最新的版本是2.2。进行Windows网络编程,你需要在你的程序中包含WINSOCK2.H或MSWSOCK.H,同时你需要添加引入库WS2_32. LIB或WSOCK32.LIB。
Socket的英文原意是“孔”或“插座”,怎么会引入到Internet中呢?在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。
所谓Socket通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。 以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
Sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCP的socket编程是采用的流式套接字。
二、重要的Socket API
重要的Socket API:java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。
1. Accept方法用于产生”阻塞”,直到接受到一个连接,并且返回一个客户端的Socket对象实例。”阻塞”是一个术语,它使程序运行暂时”停留”在这个地方,直到一个会话产生,然后程序继续;通常”阻塞”是由循环产生的。
2. getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
3. getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。 注意:其中getInputStream和getOutputStream方法均可能会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
三、如何开发一个Server-Client模型的程序
服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。 Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。
四、经典练习:阻塞模式下的Socket编程
下面是一个简单的服务器和客户端示例代码。
1.阻塞模式下的socket编程,总结设计服务器端程序的步骤:
① 初始化Windows Socket;
② 创建一个监听的Socket;
③ 设置服务器地址信息,并将监听端口绑定到这个地址上;
④ 开始监听;
⑤ 接受客户端连接;
⑥ 和客户端通信;
⑦ 结束服务并清理Windows Socket和相关数据,或者返回第4步。
TCPServer部分:
#include <winsock2.h>
void main(void)
WSADATA wsaData;
SOCKET ListeningSocket;
SOCKET NewConnection;
SOCKADDR_IN ServerAddr;
SOCKADDR_IN ClientAddr;
int Port = 5150;
//初始化Windows Socket 2.2
WSAStartup(MAKEWORD(2, 2), &wsaData);
//创建一个新的Socket来监听客户端的连接请求
ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//填写服务器地址信息
//端口为5150
//IP地址为INADDR_ANY,注意使用htonl将IP地址转换为网络格式
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
//绑定监听端口
bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr));
//开始监听,指定最大同时连接数为5
listen(ListeningSocket, 5);
//接受新的连接
NewConnection = accept(ListeningSocket, (SOCKADDR *)&ClientAddr, &ClientAddrLen));
//新的连接建立后,就可以互相通信了,在这个简单的例子中,我们直接关闭连接
//并关闭监听Socket,然后退出应用程序
closesocket(NewConnection);
closesocket(ListeningSocket);
//释放Windows Socket DLL的相关资源
WSACleanup();
2.阻塞模式下的socket编程,总结设计客户端程序的步骤:
① 初始化Windows Socket;
② 创建一个监听的Socket;
③ 设置客户端地址信息,并将监听端口绑定到这个地址上;
④ 向服务器发出连接请求;
⑤ 新的连接建立后,可以互相通信;
⑥ 结束通信时,关闭连接,关闭监听Socket,并释放Windows Socket DLL的相关资源。
TCPClient部分:
#include <winsock2.h>
void main(void)
WSADATA wsaData;
SOCKET s;
SOCKADDR_IN ServerAddr;
int Port = 5150;
//初始化Windows Socket 2.2
WSAStartup(MAKEWORD(2,2), &wsaData);
//创建一个新的Socket来连接服务器
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 填写客户端地址信息
// 端口为5150
// 服务器IP地址为"136.149.3.29",注意使用inet_addr将IP地址转换为网络格式
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = inet_addr("136.149.3.29");
//向服务器发出连接请求
connect(s, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr));
//新的连接建立后,就可以互相通信了,在这个简单的例子中,我们直接关闭连接,
//并关闭监听Socket,然后退出应用程序
closesocket(s);
// 释放Windows Socket DLL的相关资源
WSACleanup();
3.小结
socket编程中有一些成对的函数,总结如下:
① 初始化和释放dll相关资源函数,WSAStartup和WSACleanup;
② socket的创建和关闭函数,socket和closesocket;
③ 客户端的connect函数和服务器的accept函数,创建连接和接受连接;
④ 数据通信时的发送数据send函数和接受数据recv函数;
⑤ 注意服务器端程序中创建有两个socket,分工明确,一个监听客户端信息,一个用来协助数据的通信,另外,还有绑定监听端口函数bind,设置连接数函数listen等。
以上是关于Windows网络编程:阻塞模式下的Socket编程的主要内容,如果未能解决你的问题,请参考以下文章