IP 地址:InetAddress
- 唯一的标识Internet 上的计算机
- 本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost
- 不易记忆 192.168.20.165
端口号标识正在计算机上运行的进程(程序)
- 不同的进程有不同的端口号
- 被规定为一个 16 位的整数 0~65535。其中,0~1023被预先定义的服务通信占用(如MySql占用端口3306,http占用端口80等)。除非我们需要访问这些特定服务,否则,就应该使用 1024~65535 这些端口中的某一个进行通信,以免发生端口冲突。
- 端口号与IP地址的组合得出一个网络套接字。
1.1.1 InetAddress类
InetAddress类没有提供公共的构造器,而是提供了如下两个静态方法来获取InetAddress实例。
| getByName(String host) | 给定主机名,返回 InetAddress |
| getByAddress | 给定IP地址,返回 InetAddress |
其他常用的方法
| 返回本机地址 | |
获取IP地址的主机名 | ||
获取IP地址字符串 | ||
| isReachable | 测试是否可以到达该地址 |
获取此IP地址的完全限定域名 |
//创建一个InetAddress对象
InetAddress inet =InetAddress.getByName("www.wuhen6.com");
System.out.println(inet);
String hostname = inet.getHostName();
String ip = inet.getHostAddress();
System.out.println("hostname:"+hostname +" ip:" +ip);
//获取本地地址
InetAddress localaddr = InetAddress.getLocalHost();
System.out.println(localaddr);
System.out.println(InetAddress.getLoopbackAddress());
1.1.2 Socket-TCP
//创建一个InetAddress对象
InetAddress inet =InetAddress.getByName("www.wuhen6.com");
System.out.println(inet);
String hostname = inet.getHostName();
String ip = inet.getHostAddress();
System.out.println("hostname:"+hostname +" ip:" +ip);
//获取本地地址
InetAddress localaddr = InetAddress.getLocalHost();
System.out.println(localaddr);
System.out.println(InetAddress.getLoopbackAddress());
通信模型
基本流程
客户端Socket的工作过程包含以下四个基本的步骤:
1. 创建Socket:根据指定服务端的 IP 地址或端口号构造 Socket类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
2. 打开连接到Socket 的输入/出流:使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输
3. 按照一定的协议对Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
4. 关闭Socket:断开客户端到服务器的连接,释放线路
服务器程序的工作过程包含以下四个基本的步骤:
1. 调用ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
2. 调用accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
3. 调用该Socket类对象的getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
4. 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。
Socket类的常用方法
方法 | 功能 |
InetAddress getLocalAddress() | 返回对方Socket中的IP的InetAddress对象 |
int getLocalPort() | 返回本地Socket中的端口号 |
InetAddress getInetAddress() | 返回对方Socket中IP地址 |
int getPort() | 返回对方Socket中的端口号 |
void close() throws IOException | 关闭Socket,不可在以后的网络连接中使用,除非创建新的套接字 |
InputStream getInputStream() throws IOException | 获取与Socket相关联的字节输入流,用于从Socket中读数据。 |
OutputStream getOutputStream() throws IOException | 获取与Socket相关联的字节输出流,用于向Socket中写数据。 |
ServerSocket类的常用方法
方 法 | 功 能 |
Socket accept() throws IOException | 等待客户端的连接请求,返回与该客户端进行通信用的Socket对象 |
void setSoTimeout(int timeout) throws SocketException | 设置accept()方法等待连接的时间为timeout毫秒。若时间已到,还没有客户端连接,则抛出InterruptedIOException异常,accept()方法不再阻塞,该倾听Socket可继续使用。若timeout值为0,则表示accept()永远等待。该方法必须在倾听Socket创建后,在accept()之前调用才有效。 |
void close()throws IOException | 关闭监听Socket |
InetAddress getInetAddress() | 返回此服务器套接字的本地地址 |
int getLocalPort() | 返回此套接字在其上监听的端口号 |
SocketAddress getLocalSocketAddress() | 返回此套接字绑定的端点的地址 |
1.1.2.1 客户端发送信息给服务端,服务端打印在控制台
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.junit.Test;
//客户端发送信息给服务端,服务端打印在控制台
public class TestTCP1 {
@Test
public void client() throws UnknownHostException, IOException{
//1创建 Socket
Socket socket =new Socket("127.0.0.1", 9000);
//2打开连接到 Socket输出流
OutputStream os = socket.getOutputStream();
//3按照一定的协议对 Socket进行写操作
os.write("你好,我是客户端".getBytes());
//4关闭 Socket
os.close();
socket.close();
}
@Test
public void server() throws IOException{
//1创建 Socket
ServerSocket ss = new ServerSocket(9000);
//2调用 accept():监听连接请求
Socket s = ss.accept();
//3打开连接到 Socket的输入流
InputStream is = s.getInputStream();
//3按照一定的协议对 Socket进行读操作
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1){
String str = new String(b,0,len);
System.out.println(str);
}
//4关闭 Socket
is.close();
s.close();
ss.close();
}
}
1.1.2.2 客户端发送信息给服务端,服务端给予反馈
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.junit.Test;
//客户端发送信息给服务端,服务端给予反馈
public class TestTCP2 {
@Test
public void client() throws UnknownHostException, IOException{
//1创建 Socket
Socket socket = new Socket("127.0.0.1", 9000);
//2打开连接到 Socket输出流
OutputStream os = socket.getOutputStream();
//3按照一定的协议对 Socket进行写操作
os.write("你好,我是客户端".getBytes());
//表明客户端给服务端发送的内容结束
socket.shutdownOutput();
//4按照一定的协议对 Socket进行读操作
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1){
String str = new String(b,0,len);
System.out.println(str);
}
//5关闭 Socket
is.close();
os.close();
socket.close();
}
@Test
public void server() throws IOException{
//1创建 Socket
ServerSocket ss = new ServerSocket(9000);
//2调用 accept():监听连接请求
Socket s = ss.accept();
//3打开连接到 Socket的输入流
InputStream is = s.getInputStream();
//4按照一定的协议对 Socket进行读操作
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1){
String str = new String(b,0,len);
System.out.println(str);
}
//5按照一定的协议对 Socket进行写操作
OutputStream os = s.getOutputStream();
os.write("你好,我是服务端".getBytes());
//6关闭 Socket
os.close();
is.close();
s.close();
ss.close();
}
}
1.1.2.3 客户端发送文件给服务端,服务端保存到本地,并返回“发送成功”给客户端,然后关闭相应的连接
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.junit.Test;
//客户端发送文件给服务端,服务端保存到本地,并返回“发送成功”给客户端,然后关闭相应的连接
public class TestTCP3 {
@Test
public void client() throws UnknownHostException, IOException{
//1创建 Socket
Socket socket = new Socket("127.0.0.1", 9000);
//2打开连接到 Socket输出流
FileInputStream fis = new FileInputStream("bg.png");
OutputStream os = socket.getOutputStream();
//3按照一定的协议对 Socket进行写操作
byte[] b1 = new byte[1024];
int len1;
while((len1=fis.read(b1))!=-1){
os.write(b1,0,len1);
}
//表明客户端给服务端发送的内容结束
socket.shutdownOutput();
//4按照一定的协议对 Socket进行读操作
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1){
String str = new String(b,0,len);
System.out.println(str);
}
//5关闭 Socket
is.close();
os.close();
fis.close();
socket.close();
}
@Test
public void server() throws IOException{
//1创建 Socket
ServerSocket ss = new ServerSocket(9000);
//2调用 accept():监听连接请求
Socket s = ss.accept();
//3打开连接到 Socket的输入流
InputStream is = s.getInputStream();
FileOutputStream fos = new FileOutputStream("20.png");
//4按照一定的协议对 Socket进行读操作
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1){
fos.write(b,0,len);
}
//5按照一定的协议对 Socket进行写操作
OutputStream os = s.getOutputStream();
os.write("文件已收到!".getBytes());
//6关闭 Socket
os.close();
is.close();
fos.close();
s.close();
ss.close();
}
}
1.1.3 Socket-UDP
流程:
1. DatagramSocket与DatagramPacket
2. 建立发送端,接收端
3. 建立数据包
4. 调用Socket的发送、接收方法
5. 关闭Socket
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.junit.Test;
public class TestUDP {
@Test
public void client() throws UnknownHostException, IOException{
//1建立发送端
DatagramSocket ds = new DatagramSocket();
//2建立数据包
byte[] by = "hello,atguigu.com".getBytes();
DatagramPacket dp = new DatagramPacket(by,0,by.length,
InetAddress.getByName("127.0.0.1"),10000);
//3调用Socket的发送方法
ds.send(dp);
//4关闭Socket
ds.close();
}
@Test
public void server() throws IOException{
//1建立接收端
DatagramSocket ds = new DatagramSocket(10000);
//2建立数据包
byte[] by = new byte[1024];
DatagramPacket dp = new DatagramPacket(by,by.length);
//3调用Socket的接收方法
ds.receive(dp);
String str = new String(dp.getData(),0,dp.getLength());
System.out.println(str+"--"+dp.getAddress());
//4关闭Socket
ds.close();
}
}