Java TCP中的InetAddress和ServerSocket

TCP网络设计程序,是指利用Socket类编写通信程序。
1、InetAddress类
java.net包中的InetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。InetAddress类的常用方法如下:
在这里插入图片描述
例子:
使用InetAddress类的getHostName()和getHostAddress()方法获取本地主机的本机名、本机IP地址:

public class Address {
	public static void main(String[] args) {
		try {
			InetAddress IP = InetAddress.getLocalHost();// 创建InetAddress对象并实例化
			String localName = IP.getHostName();//获取本机名
			String localIP = IP.getHostAddress();//获取本机IP地址
			System.out.println("本机名:" + localName + "\n" + "本机IP地址:" + localIP);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

输出结果:在这里插入图片描述
注:InetAddress类的方法会抛出UnknownHostException 异常,该异常在主机不存在或网络连接错误时发生。

2、ServerSocket类
java.net包中的ServerSocket类用于表示服务器套接字,其主要功能是等待来自网络上的“请求”,它可通过指定的端口来等待连接的套接字。服务器套接字一次可以与一个套接字连接。如果多台客户机同时提出连接请求,服务器套接字会将请求连接的客户机存入队列中,然后从中取出一个套接字,与服务器新建的套接字连接起来。若请求连接数大于最大容纳数,则多出的连接请求被拒绝。队列的默认大小为50。
ServerSocket类的构造方法都抛出IOException异常,分别有以下几种形式:
(1)、ServerSocket():创建非绑定服务器套接字。
(2)、ServerSocket(int port):创建绑定到特定端口的服务套接字。
(3)、ServerSocket(int port,int backlog):利用指定的backlog创建服务器套接字并将其绑定到指定的本地端口号。
(4)、ServerSocket(int port,int backlog,InetAddress bindAddress):使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。这种情况适用于计算机上有多块网卡和多个IP地址的情况,用于可以明确规定ServerSocket在哪块网卡或IP地址上等待客户的连接请求。

ServerSocket类的常用方法:
在这里插入图片描述
调用ServerSocket类的accept()方法会返回一个和客户端Socket对象相连接的Socket对象,服务器端的Socket对象使用getOutputStream()方法获得的输出流将指向客户端Socket对象使用getInputStream()方法获得的那个输入流;同样,服务器端的Socket对象使用getInputStream()方法获得的输入流将指向客户端Socket对象使用getOutputStream()方法获得的那个输出流。也就是说,当服务器向输出流写入信息时,客户端通过相应的输入流就能读取,反之亦然。

注:accept()方法阻塞线程的继续执行,直到接收到客户的呼叫。如果没有客户呼叫服务器,那么System.out.println(“连接中”)语句将不会执行。语句如果没有客户请求,accept()方法没有发生阻塞,肯定是程序出现了问题。通常是使用了一个还在被其他程序占用的端口号,ServerSocket绑定没有成功。

yu = server.accept();
System.out.println("连接中");

补充:
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。例如,如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)。总之,套接字Socket=(IP地址:端口号),套接字的表示方法是点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开。每一个传输层连接唯一地被通信两端的两个端点(即两个套接字)所确定。

套接字调用流程如下图所示:
在这里插入图片描述
socket():创建套接字。

bind():指定本地地址。一个套接字用socket()创建后,它其实还没有与任何特定的本地或目的地址相关联。在很多情况下,应用程序并不关心它们使用的本地地址,这时就可以不用调用bind指定本地的地址,而由协议软件为它们选择一个。但是,在某个知名端口(Well-known Port)上操作的服务器进程必须要对系统指定本地端口。所以一旦创建了一个套接字,服务器就必须使用bind()系统调用为套接字建立一个本地地址。

connect():将套接字连接到目的地址。初始创建的套接字并未与任何外地目的地址关联。客户机可以调用connect()为套接字绑定一个永久的目的地址,将它置于已连接状态。对数据流方式的套接字,必须在传输数据前,调用connect()构造一个与目的地的TCP连接,并在不能构造连接时返回一个差错代码。如果是数据报方式,则不是必须在传输数据前调用connect。如果调用了connect(),也并不像数据流方式那样发送请求建连的报文,而是只在本地存储目的地址,以后该socket上发送的所有数据都送往这个地址,程序员就可以免去为每一次发送数据都指定目的地址的麻烦。

listen():设置等待连接状态。对于一个服务器的程序,当申请到套接字,并调用bind()与本地地址绑定后,就应该等待某个客户机的程序来要求连接。listen()就是把一个套接字设置为这种状态的函数。

accept():接受连接请求。服务器进程使用系统调用socket,bind和listen创建一个套接字,将它绑定到知名的端口,并指定连接请求的队列长度。然后,服务器调用accept进入等待状态,直到到达一个连接请求。

send()/recv()和sendto()/recvfrom():发送和接收数据 。在数据流方式中,一个连接建立以后,或者在数据报方式下,调用了connect()进行了套接字与目的地址的绑定后,就可以调用send()和reev()函数进行数据传输。

closesocket():关闭套接字。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaUDP和TCP程序的区别如下: 1. UDP是无连接的,而TCP是面向连接的。UDP不需要在发送数据之前建立连接,而TCP需要先建立连接,然后才能进行通信。 2. UDP是不可靠的,而TCP是可靠的。UDP发送数据时不会确认对方是否收到,也不会重发丢失的数据包,而TCP会确认对方是否收到数据,并在必要时重发丢失的数据包。 3. UDP发送的数据包大小限制为64KB,而TCP没有大小限制。 4. UDP发送数据时不保证顺序,而TCP保证数据的顺序。 5. UDP适用于实时性要求高、数据量小、可靠性要求不高的场景,例如视频、音频等;而TCP适用于数据量大、可靠性要求高的场景,例如文件传输、网页浏览等。 以下是JavaUDP和TCP的代码示例: UDP示例: ```java // 发送端 DatagramSocket socket = new DatagramSocket(); String message = "Hello, UDP!"; byte[] data = message.getBytes(); InetAddress address = InetAddress.getByName("127.0.0.1"); DatagramPacket packet = new DatagramPacket(data, data.length, address, 8888); socket.send(packet); socket.close(); // 接收端 DatagramSocket socket = new DatagramSocket(8888); byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); String message = new String(packet.getData(), 0, packet.getLength()); System.out.println("Received message: " + message); socket.close(); ``` TCP示例: ```java // 服务器端 ServerSocket serverSocket = new ServerSocket(8888); Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { String message = new String(buffer, 0, len); System.out.println("Received message: " + message); outputStream.write(("Server received: " + message).getBytes()); } socket.close(); serverSocket.close(); // 客户端 Socket socket = new Socket("127.0.0.1", 8888); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); outputStream.write("Hello, TCP!".getBytes()); byte[] buffer = new byte[1024]; int len = inputStream.read(buffer); String message = new String(buffer, 0, len); System.out.println("Received message: " + message); socket.close(); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值