Java套接字实现网络编程之基础篇1

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

用Java开发网络软件非常方便和强大,Java的这种力量来源于他独有的一套强大的用于网络的 API,这些 API是一系列的类和接口,均位于包java.net和javax.net中。在这篇文章中我们将介绍套接字(Socket)慨念,同时以实例说明如何使 用Network API操纵套接字,在完成本文后,你将具备编写网络低端通讯软件的能力。

什么是套接字(Socket)?



Network API是典型的用于基于TCP/IP网络Java程序与其他程序通讯,Network API依靠Socket进行通讯。Socket可 以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息 能传送到其他程序中。如图1 

我们来分析一下图1,Host A上的程序A将一段信息写入Socket中,Socket的内容被Host A的网络管理软件访问,并将这段信息通 过Host A的网络接口卡发送到Host B,Host B的网络接口卡接收到这段信息后,传送给Host B的网络管理软件,网络管理软件将这段信息 保存在Host B的Socket中,然后程序B才能在Socket中阅读这段信息。

假设在图1的网络中添加第三个主机Host C,那么Host A怎么知道信息被正确传送到Host B而不是被传送到Host C中了呢?基于 TCP/IP网络中的每一个主机均被赋予了一个唯一的IP地址,IP地址是一个32位的无符号整数,由于没有转变成二进制,因此通常以小数点分隔,如: 198.163.227.6,正如所见IP地址均由四个部分组成,每个部分的范围都是0-255,以表示8位地址。

值得注意的是IP地址都是32位地址,这是IP协议版本4(简称Ipv4)规定的,目前由于IPv4地址已近耗尽,所以IPv6地址正逐渐代替Ipv4地址,Ipv6地址则是128位无符号整数。

假设第二个程序被加入图1的网络的Host B中,那么由Host A传来的信息如何能被正确的传给程序B而不是传给新加入的程序呢?这是因为每一个基于 TCP/IP网络通讯的程序都被赋予了唯一的端口和端口号,端口是一个信息缓冲区,用于保留Socket中的输入/输出信息,端口号是一个16位无符号整 数,范围是0-65535,以区别主机上的每一个程序(端口号就像房屋中的房间号),低于256的短口号保留给标准应用程序,比如pop3的端口号就是 110,每一个套接字都组合进了IP地址、端口、端口号,这样形成的整体就可以区别每一个套接字t,下面我们就来谈谈两种套接字:流套接字和自寻址数据套 接字。

流套接字(Stream Socket)

无论何时,在两个网络应用程序之间发送和接收信息时都需要建立一个可靠的连接,流套接字依靠TCP协议来保证信息正确到达目的地,实际 上,IP包有可能在网络中丢失或者在传送过程中发生错误,任何一种情况发生,作为接受方的 TCP将联系发送方TCP重新发送这个IP包。这就是所谓的在 两个流套接字之间建立可靠的连接。

流套接字在C/S程序中扮演一个必需的角色,客户机程序(需要访问某些服务的网络应用程序)创建一个扮演服务器程序的主机的IP地址和服务器程序(为客户端应用程序提供服务的网络应用程序)的端口号的流套接字对象。

客户端流套接字的初始化代码将IP地址和端口号传递给客户端主机的网络管理软件,管理软件将IP地址和端口号通过NIC传递给服务器端主机;服务器端主机 读到经过NIC传递来的数据,然后查看服务器程序是否处于监听状态,这种监听依然是通过套接字和端口来进行的;如果服务器程序处于监听状态,那么服务器端 网络管理软件就向客户机网络管理软件发出一个积极的响应信号,接收到响应信号后,客户端流套接字初始化代码就给客户程序建立一个端口号,并将这个端口号传 递给服务器程序的套接字(服务器程序将使用这个端口号识别传来的信息是否是属于客户程序)同时完成流套接字的初始化。

如果服务器程序没有处于监听状态,那么服务器端网络管理软件将给客户端传递一个消极信号,收到这个消极信号后,客户程序的流套接字初始化代码将抛出一个异常对象并且不建立通讯连接,也不创建流套接字对象。这种情形就像打电话一样,当有人的时候通讯建立,否则电话将被挂起。

这部分的工作包括了相关联的三个类:InetAddress, Socket, 和 ServerSocket。 InetAddress对象描绘了32 位或128位IP地址,Socket对象代表了客户程序流套接字,ServerSocket代表了服务程序流套接字,所有这三个类均位于包 java.net中。

InetAddress类

InetAddress类在网络API套接字编程中扮演了一个重要角色。参数传递给流套接字类和自寻址套接字类构造器或非构造器方法。 InetAddress描述了32位或64位IP地址,要完成这个功能,InetAddress类主要依靠两个支持类Inet4Address 和  Inet6Address,这三个类是继承关系,InetAddrress是父类,Inet4Address 和 Inet6Address是子类。

由于InetAddress类只有一个构造函数,而且不能传递参数,所以不能直接创建InetAddress对象,比如下面的做法就是错误的:

InetAddress ia = new InetAddress ();

但我们可以通过下面的5个工厂方法创建来创建一个InetAddress对象或InetAddress数组:

 . getAllByName(String host)方法返回一个InetAddress对象的引用,每个对象包含一个表示相应主机名的单独的IP 地址,这个IP地址是通过host参数传递的,对于指定的主机如果没有IP地址存在那么这个方法将抛出一个UnknownHostException 异 常对象。

 . getByAddress(byte [] addr)方法返回一个InetAddress对象的引用,这个对象包含了一个Ipv4地址或Ipv6 地址,Ipv4地址是一个4字节数组,Ipv6地址是一个16字节地址数组,如果返回的数组既不是4字节的也不是16字节的,那么方法将会抛出一个 UnknownHostException异常对象。

 . getByAddress(String host, byte [] addr)方法返回一个InetAddress对象的引用,这个 InetAddress对象包含了一个由host和4字节的addr数组指定的IP地址,或者是host和16字节的addr数组指定的IP地址,如果这 个数组既不是4字节的也不是16位字节的,那么该方法将抛出一个UnknownHostException异常对象。

 . getByName(String host)方法返回一个InetAddress对象,该对象包含了一个与host参数指定的主机相对应的IP地址,对于指定的主机如果没有IP地址存在,那么方法将抛出一个UnknownHostException异常对象。

 . getLocalHost()方法返回一个InetAddress对象,这个对象包含了本地机的IP地址,考虑到本地主机既是客户程序主机又是服务器程序主机,为避免混乱,我们将客户程序主机称为客户主机,将服务器程序主机称为服务器主机。

上面讲到的方法均提到返回一个或多个InetAddress对象的引用,实际上每一个方法都要返回一个或多个 Inet4Address/Inet6Address对象的引用,调用者不需要知道引用的子类型,相反调用者可以使用返回的引用调用 InetAddress对象的非静态方法,包括子类型的多态以确保重载方法被调用。

InetAddress和它的子类型对象处理主机名到主机IPv4或IPv6地址的转换,要完成这个转换需要使用域名系统,下面的代码示范了如何通过调用 getByName(String host)方法获得InetAddress子类对象的方法,这个对象包含了与host参数相对应的IP地址:

InetAddress ia = InetAddress.getByName ("www.javajeff.com"));

一但获得了InetAddress子类对象的引用就可以调用InetAddress的各种方法来获得InetAddress子类对象中的IP地址信 息,比如,可以通过调用getCanonicalHostName()从域名服务中获得标准的主机名;getHostAddress()获得IP地址, getHostName()获得主机名,isLoopbackAddress()判断IP地址是否是一个loopback地址。

List1 是一段示范代码:InetAddressDemo

// InetAddressDemo.java

import java.net.*;

class InetAddressDemo

{

 public static void main (String [] args) throws UnknownHostException

 {

String host = "localhost";

if (args.length == 1)

 host = args [0];

InetAddress ia = InetAddress.getByName (host);

System.out.println ("Canonical Host Name = " +

ia.getCanonicalHostName ());

System.out.println ("Host Address = " +

ia.getHostAddress ());

System.out.println ("Host Name = " +

ia.getHostName ());

System.out.println ("Is Loopback Address = " +

ia.isLoopbackAddress ());

 }

}

当无命令行参数时,代码输出类似下面的结果:

Canonical Host Name = localhost

Host Address = 127.0.0.1

Host Name = localhost

Is Loopback Address = true 

InetAddressDemo给了你一个指定主机名作为命令行参数的选择,如果没有主机名被指定,那么将使用localhost(客户机的), InetAddressDemo通过调用getByName(String host)方法获得一个InetAddress子类对象的引用,通过这个引用 获得了标准主机名,主机地址,主机名以及IP地址是否是loopback地址的输出。


Socket类

当客户程序需要与服务器程序通讯的时候,客户程序在客户机创建一个socket对象,Socket类有几个构造函数。两个常用的构造函 数是 Socket(InetAddress addr, int port) 和 Socket(String host, int port),两个 构造函数都创建了一个基于Socket的连接服务器端流套接字的流套接字。对于第一个InetAddress子类对象通过addr参数获得服务器主机的 IP地址,对于第二个函数host参数包被分配到InetAddress对象中,如果没有IP地址与host参数相一致,那么将抛出 UnknownHostException异常对象。两个函数都通过参数port获得服务器的端口号。假设已经建立连接了,网络API将在客户端基于 Socket的流套接字中捆绑客户程序的IP地址和任意一个端口号,否则两个函数都会抛出一个IOException对象。

如果创建了一个Socket对象,那么它可能通过调用Socket的 getInputStream()方法从服务程序获得输入流读传送来的信息,也可能 通过调用Socket的 getOutputStream()方法获得输出流来发送消息。在读写活动完成之后,客户程序调用close()方法关闭流和流 套接字,下面的代码创建了一个服务程序主机地址为198.163.227.6,端口号为13的Socket对象,然后从这个新创建的Socket对象中读 取输入流,然后再关闭流和Socket对象。 

 

Socket s = new Socket ("198.163.227.6", 13);

InputStream is = s.getInputStream ();

// Read from the stream.

is.close ();

s.close ();

接下面我们将示范一个流套接字的客户程序,这个程序将创建一个Socket对象,Socket将访问运行在指定主机端口10000上的服务程序,如 果访问成功客户程序将给服务程序发送一系列命令并打印服务程序的响应。List2使我们创建的程序SSClient的源代码:Listing 2:  SSClient.java

// SSClient.java

import java.io.*;

import java.net.*; 

class SSClient

{

 public static void main (String [] args)

 {

String host = "localhost";

// If user specifies a command-line argument, that argument

// represents the host name.

if (args.length == 1)

 host = args [0];

BufferedReader br = null;

PrintWriter pw = null;

Socket s = null;

try

{

 // Create a socket that attempts to connect to the server

 // program on the host at port 10000.

 s = new Socket (host, 10000);

 // Create an input stream reader that chains to the socket's

 // byte-oriented input stream. The input stream reader

 // converts bytes read from the socket to characters. The

 // conversion is based on the platform's default character

 // set.

 InputStreamReader isr;

 isr = new InputStreamReader (s.getInputStream ());

 // Create a buffered reader that chains to the input stream

 // reader. The buffered reader supplies a convenient method

 // for reading entire lines of text.

 br = new BufferedReader (isr);

 // Create a print writer that chains to the socket's byte-

 // oriented output stream. The print writer creates an

 // intermediate output stream writer that converts

 // characters sent to the socket to bytes. The conversion

 // is based on the platform's default character set.

 pw = new PrintWriter (s.getOutputStream (), true);

 // Send the DATE command to the server.

 pw.println ("DATE");

 // Obtain and print the current date/time.

 System.out.println (br.readLine ());

 // Send the PAUSE command to the server. This allows several

 // clients to start and verifies that the server is spawning

 // multiple threads.

 pw.println ("PAUSE");

 // Send the DOW command to the server.

 pw.println ("DOW");

 // Obtain and print the current day of week.

 System.out.println (br.readLine ());

 // Send the DOM command to the server.

 

 pw.println ("DOM");

 // Obtain and print the current day of month.

 System.out.println (br.readLine ());

 // Send the DOY command to the server.

 pw.println ("DOY");

 // Obtain and print the current day of year.

 System.out.println (br.readLine ());

}

catch (IOException e)

{

 System.out.println (e.toString ());

}

finally

{

 try

 {

if (br != null)

 br.close ();

if (pw != null)

 pw.close ();

if (s != null)

 s.close ();

 }

 catch (IOException e)

 {

}

}

 }

}

运行这段程序将会得到下面的结果:

Tue Jan 29 18:11:51 CST 2002

TUESDAY

29

29

SSClient创建了一个Socket对象与运行在主机端口10000的服务程序联系,主机的IP地址由host变量确定。SSClient将获 得Socket的输入输出流,围绕BufferedReader的输入流和PrintWriter的输出流对字符串进行读写操作就变得非常容易, SSClient个服务程序发出各种date/time命令并得到响应,每个响应均被打印,一旦最后一个响应被打印,将执行 Try/Catch/Finally结构的Finally子串,Finally子串将在关闭Socket之前关闭BufferedReader 和  PrintWriter。

在SSClient源代码编译完成后,可以输入java SSClient 来执行这段程序,如果有合适的程序运行在不同的主机上,采用主机名/IP地址 为参数的输入方式,比如www.sina.com.cn是运行服务器程序的主机,那么输入方式就是 java SSClientwww.sina.com.cn。

 
三角形面积的计算 三角形的面积计算以及判断 运用了jsp javabean希望对大家有帮助 立即下载

相关推荐

三角形面积,利用Socket编程实现

服务器客户实现三角形面积,利用Socket编程实现

Java基于TCP的Socket编程练习

环境:Notpad ++ 6.0 + JDK 6.0.31 问题:使用套接字编写客户服务器程序实现客户服务器交互计算客户三角形3个边的长度发给服务器服务器计算三角形的面积返回给客户。 解决:利用JavaSocket编程客户端发送数据,服务端接收数据,并进行相应的处理。 代码: TcpServer.java: import java.io.BufferedRe...

数据库天地 1001

利用套接字进行网络编程

利用套接字进行网络编程

Tom_Lang_666的博客 667

套接字连接的三种方式

套接字连接的三种方式document.title=" 套接字连接的三种方式 - "+document.title       如何使用套接字进行通信呢?服务器程序会首先启动,然后它就只是等待来自客户的请求.通常,由客户程序发起一个连接,指向它希望连接服务器.当客户请求时,服务器可以接受这个连接,变即启动一个特定的服务器套接字,通过它与客户套接字相连.为了支持这种操作模式.可以

软体虫的专栏 2531

Socket 编程

Socket 也叫做“套接字”, 计算网络通信中最为基础的内容,通过对TCP/IP协议的封装提供了在不同主机之间进行通信的功能。 当通过浏览器访问一个网站的时候,浏览器会为我们打开一个套接字,通过套接字建立与服务器之间的连接连接成功后服务器提供对访问的响应并返回内容最终在浏览器中显示来。 分为 服务器客户服务器端 - 创建套接字 - 绑定端口 - 监听端口 - 接受连接 - 接收...

Allen_by的博客 401

Java套接字实现网络编程基础(1)

Java开发网络软件非常方便和强大,Java的这种力量来源于他独有的一套强大的用于网络的 API,这些API是一系列的类和接口,均位于包java.net和javax.net中。在这文章中我们将介绍套接字(Socket)慨念,同时以实例说明如何使用Network API操纵套接字,在完成本文后,你将具备编写网络低端通讯软件的能力。 什么是套接字(Socket)? Network API是

u011905238的专栏 645

java变形金刚_Java套接字实现网络编程基础(1)

Java开发网络软件非常方便和强大,Java的这种力量来源于他独有的一套强大的用于网络的 API,这些API是一系列的类和接口,均位于包java.net和javax.net中。在这文章中我们将介绍套接字(Socket)慨念,同时以实例说明如何使用Network API操纵套接字,在完成本文后,你将具备编写网络低端通讯软件的能力。什么是套接字(Socket)?Network API是典型的用于基...

weixin_32311823的博客 233

JAVA网络编程——socket套接字的介绍上(详细)

大家好!今天笔者分享一关于Socket 套接字的博客,希望能为正在学习网络编程的读者提供一些帮助。梳理网络通信的基础概念本文还将顺带总结一些与 Socket 密切相关的基础知识,包括:IP 地址、端口号、网络协议、五元组、协议分层模型的作用与内容、TCP/UDP 区别、Socket API 的使用方式,以及如何通过代码模拟客户端/服务器之间的通信过程。理解客户端与服务器的数据交互。

cjejwe的博客 6307

网络编程网络编程Socket 套接字认识

为什么需要网络编程,什么是网络编程Socket 套接字的简要认识

bit me的博客 2789

JavaEE初阶】 网络编程基础Socket套接字

网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。当然,我们只要满足进程不同就行;所以即便是同一个主机,只要是不同进程,基于网络来传输数据,也属于网络编程特殊的情况,对于开发来说,在条件有限的情况下,一般也都是在一个主机中运行多个进程来完成网络编程。但是,我们一定要明确,我们的目的是提供网络上不同主机,基于网络来传输数据资源:进程A:编程来获取网络资源进程B:编程来提供网络资源。

m0_71731682的博客 1781

初始JavaEE —— 网络编程(2):了解套接字,从0到1实现回显服务器

TCP 与 UDP Socket套接字 :UDP 、TCP

我要学编程的博客 4443

Java网络编程套接字

文章目录1网络编程基础2、什么是网络编程3、网络编程中的基本概念3.1、发送端和接收端3.2 请求和响应3.3 客户端和服务端3.4 常见的客户端服务端模型4、Socket套接字4.1 概念4.2 分类5、Java数据报套接字通信模型6、Java套接字通信模型7、Socket编程注意事项8、UDP数据报套接字编程8.1 DatagramSocket API8.2 DatagramPacket API8.3 InetSocketAddress API 1网络编程基础 为什么需要网络编程? 丰富的网络资源

weixin_58030464的博客 2665

Java网络编程之UDP和TCP套接字

介绍使用Java如何进行网络编程, 主要有UDP和TCP两种方式; UDP的特点是无连接, 不可靠传输, 面向数据报, 全双工; TCP的特点是有连接, 可靠传输, 面向字节流, 全双工.

trong_ 的烂笔头 3782

JAVA网络编程——socket套接字的介绍下(详细)

各位读者大家好,今天笔者继续更新socket套接字的下半部分,这部分承接上半的内容接着往下写JAVA网络编程——socket套接字的介绍上(详细)-CSDN博客上半博客笔者主要汇总了一些网络编程基础知识,并介绍了UDP数据报套接字编程和代码案例实现了一个简单的回显服务器客户1.TCP流套接字编程 与 UDP 数据报套接字的区别,并结合具体代码,说明两者在实现方式上的差异。2.TCP流套接字 编程常用 API 和代码示例,并尝试引入多线程思路对服务端代码进行优化。

cjejwe的博客 3223

网络编程套接字(1)

网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)当然,我们只要满足进程不同就行;所以即使是同一个主机,只要是不同的进程,基于网络来传输数据,也属于网络编程特殊的,对于开发来说,在条件有限的情况下,一般也是在一个主机中运行多个进程来实现网络编程.但是我们一定要明确,我们的目的是提供网络上不同主机,基于网络来传输数据资源进程A:编程来获取网络资源.进程B:编程来提供网络资源.

asdssadddd的博客 1613

网络编程套接字(Socket)详解 V✪ω✪V

网络编程套接字(Socket)详解 V✪ω✪V

2302_79862386的博客 2215

网络编程套接字

在本文中,会介绍一些关于网络编程基础知识Socket的一些api会在文章末尾运用所讲知识做一个基于网络的回显的代码是UDP Socket,⽤于发送和接收UDP数据报。方法签名方法说明创建⼀个UDP数据报套接字Socket,绑定到本机任意⼀个随机端⼝(⼀般⽤于客⼾端)创建⼀个UDP数据报套接字Socket,绑定到本机指定的端⼝(⼀般⽤于服务端)方法签名方法说明从此套接字接收数据报(如果没有接收到数据报,该⽅法会阻塞等待)从此套接字发送数据报包(不会阻塞等待,直接发送)

daydayup 2035

JavaEE精炼宝库】 网络编程套接字——初识网络编程 | UDP数据报套接字编程

网络编程中,套接字Socket)是实现网络通信的重要工具。套接字主要有两种类型:1.流式套接字(Stream Socket)2.数据报套接字(Datagram Socket)。今天就让我们来深入学习一下。

2301_80035594的博客 3210
上一篇: 博客没设置好,现在好了
下一篇: Java套接字实现网络编程之基础篇2
kevin_long
博客等级 码龄19年 30粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值