详细介绍:java基础--网络编程(13)
一,java网络编程中的常用类
1.InetAddress的使用
作用:封装计算机的IP地址和域名
特点:这个类没有构造方法。如果要得到对象,只能通过getLocalHost()、getByName()等静态方法创建对象
01.获取本机信息
获取本机信息需要使用getLocalHost方法创建InetAddress 对象。getLocalHost() 方法返回一个InetAddress对象,这个对象包含了本机的IP地址,计算机名等信息。
public class InetTest {
public static void main(String[] args)throws Exception {
//实例化InetAddress对象
InetAddress inetAddress = InetAddress.getLocalHost();
//返回当前计算机的IP地址
System.out.println(inetAddress.getHostAddress());
//返回当前计算机名
System.out.println(inetAddress.getHostName());
}
}
02。根据域名获取计算机信息
根据域名获取计算机信息时需要使用getByName(“域名”)方法创建InetAddress对象
public class InetTest2 {
public static void main(String[] args)throws Exception {
InetAddress inetAddress =
InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress.getHostAddress());
System.out.println(inetAddress.getHostName());
}
}
03.根据IP获取计算机信息
根据IP地址获取计算机信息时需要使用getByName(“IP”)方法创建InetAddress 对象。
public class InetTest3 {
public static void main(String[] args)throws Exception {
InetAddress inetAddress =
InetAddress.getByName("39.156.66.14");
System.out.println(inetAddress.getHostAddress());
System.out.println(inetAddress.getHostName());
}
}
2.InetSocketAddress的使用
作用:包含IP和端口信息,常用于Socket通信。此类实现 IP 套接字地址(IP 地址 + 端口号),不依赖任何协议。
InetSocketAddress 相比较 InetAddress 多了一个端口号,端口的作用:一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通 过1个IP地址来实现。
那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区分不同的服务的
public class InetSocketTest {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress = new
InetSocketAddress("www.baidu.com",80);
System.out.println(inetSocketAddress.getAddress().getHostAddress(
));
System.out.println(inetSocketAddress.getHostName());
}
}
3.URL类的使用
IP 地址标识了Internet上唯一的计算机,而URL则标识了这些计算机上的资源。URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
为了方便程序员编程,JDK中提供了URL类,该类的全名是java.net.URL,有了这样 一个类,就可以使用它的各种方法来对URL对象进行分割、合并等处理。
public class UrlTest {
public static void main(String[] args)throws Exception {
URL url = new
URL("http://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=ba
idu&wd=itbz");
System.out.println("获取与此URL相关联协议的默认端口:"+url.getDefaultPort());
System.out.println("访问资源:"+url.getFile());
System.out.println("主机名"+url.getHost());
System.out.println("访问资源路径:"+url.getPath());
System.out.println("协议:"+url.getProtocol());
System.out.println("参数部分:"+url.getQuery());
}
}
二,TCP通信的实现
1.TCP通信介绍
前边我们提到TCP协议是面向连接的协议,在通信时客户端与服务器端必须建立连接。 在网络通信中,第一次主动发起通信的程序被称作客户端(Client)程序,简称客户端,而在第一次通信中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通信建立,则客户端和服务器端完全一样,没有本质的区别。
“请求-响应”模式:
Socket类:发送TCP消息。
ServerSocket类:创建服务器。
套接字Socket是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在通过网络连接的不同机器上。换句话说,套接字起到通信端点的作用。
单个套接字是一个端点,而一对套接字则构成一个双向通信信道,使非关联进程可以在本地或通过网络进行数据交换。一旦建立套接字连接,数据即可在相同或不同的系统中双向或单向发送,直到其中一个端点关闭连接。套接字与主机地址和端口地址相关联。主机地址就是客户端或服务器程序所在的主机的IP地址。端口地址是指客户端或服务器程序使用的主机的通信端口。
在客户端和服务器中,分别创建独立的Socket,并通过Socket的属性,将两个Socket 进行连接,这样,客户端和服务器通过套接字所建立的连接使用输入输出流进行通信。
TCP/IP 套接字是最可靠的双向流协议,使用TCP/IP可以发送任意数量的数据。
实际上,套接字只是计算机上已编号的端口。如果发送方和接收方计算机确定好端口,他们就可以通信了。
客户端与服务器端的通信关系图:

TCP/IP通信连接的简单过程:
位于A计算机上的TCP/IP软件向B计算机发送包含端口号的消息,B计算机的TCP/IP 软件接收该消息,并进行检查,查看是否有它知道的程序正在该端口上接收消息。如果有,他就将该消息交给这个程序。
要使程序有效地运行,就必须有一个客户端和一个服务器。
通过Socket的编程顺序:
1. 创建服务器ServerSocket,在创建时,定义ServerSocket的监听端口(在这个端口接收客户端发来的消息)。
2. ServerSocket 调用 accept()方法,使之处于阻塞状态。
3.创建客户端Socket,并设置服务器的IP及端口。
4.客户端发出连接请求,建立连接。
5.分别取得服务器和客户端Socket的InputStream和OutputStream。
6.利用Socket和ServerSocket 进行数据传输。
7。关闭流及Socket。
2.入门案例
01。创建服务端
public class BasicSocketServer {
public static void main(String[] args) {
Socket socket = null;
BufferedReader br = null;
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器启动等待监听。。。。");
//开启端口的监听
socket = serverSocket.accept();
//读取客户端发送的消息
br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket !=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
02.创建客户端
public class BasicSocketClient {
public static void main(String[] args) {
Socket socket = null;
PrintWriter pw= null;
try {
//创建Socket对象,两个参数:1,服务端的IP地址,2,服务端所监听的端口
socket = new Socket("127.0.0.1",8888);
pw = new PrintWriter(socket.getOutputStream());
pw.println("服务端您好!");
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(pw != null){
pw.close();
}
if(socket !=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.TCP单向通信
单向通信是指通信双方中,一方固定为发送端,一方则固定为接收端。
01.创建服务端
public class OneWaySocketServer {
public static void main(String[] args) {
Socket socket = null;
BufferedReader br = null;
PrintWriter pw = null;
try{
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端启动,开始监听。。。。。");
socket = serverSocket.accept();
System.out.println("连接成功!");
//读取客户端发送的消息
br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
//向客户端写回消息的流对象
pw = new PrintWriter(socket.getOutputStream());
while(true){
String str = br.readLine();
System.out.println("客户端说:"+str);
if("exit".equals(str)){
break;
}
pw.println(str);
pw.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(pw != null){
pw.close();
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
02.创建客户端
public class OneWaySocketClient {
public static void main(String[] args) {
Socket socket = null;
Scanner scanner = null;
PrintWriter pw = null;
BufferedReader br = null;
try{
socket = new Socket("127.0.0.1",8888);
//创建键盘输入对象
scanner = new Scanner(System.in);
//创建向服务端输出消息的流对象
pw = new PrintWriter(socket.getOutputStream());
//创建读取服务端返回消息的流对象
br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
while(true){
//通过键盘输入获取需要向服务端发送的消息
String str = scanner.nextLine();
//将消息发送到服务端
pw.println(str);
pw.flush();
if("exit".equals(str)){
break;
}
//读取服务端返回的消息
String serverInput = br.readLine();
System.out.println("服务端返回的:"+serverInput);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(scanner != null){
scanner.close();
}
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(pw != null){
pw.close();
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.TCP双向通信
双向通信是指通信双方中,任何一方都可为发送端,任何一方都可为接收端。
01.创建服务端
public class TwoWaySocketServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
BufferedReader br = null;
Scanner scanner = null;
PrintWriter pw = null;
try{
serverSocket = new ServerSocket(8888);
System.out.println("服务端启动!监听端口8888。。。。");
socket = serverSocket.accept();
//创建从客户端读取消息的流对象
br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
//创建键盘输入对象
scanner = new Scanner(System.in);
//创建向客户端发送消息的输出流对象
pw = new PrintWriter(socket.getOutputStream());
while(true){
//读取客户端发送的消息
String str = br.readLine();
System.out.println("客户端说:"+str);
String keyInput = scanner.nextLine();
//发送到客户端
pw.println(keyInput);
pw.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(scanner != null){
scanner.close();
}
if(pw != null){
pw.close();
}
}
}
}
02.创建客户端
public class TwoWaySocketClient {
public static void main(String[] args) {
Socket socket = null;
Scanner scanner = null;
PrintWriter pw = null;
BufferedReader br = null;
try{
socket = new Socket("127.0.0.1",8888);
//键盘输入对象
scanner = new Scanner(System.in);
//创建向服务端发送消息的流对象
pw = new PrintWriter(socket.getOutputStream());
//创建读取服务端发送消息的流对象
br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
while(true){
String keyInput = scanner.nextLine();
pw.println(keyInput);
pw.flush();
String input = br.readLine();
System.out.println("服务端说:"+input);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(socket!= null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(pw != null){
pw.close();
}
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(scanner != null){
scanner.close();
}
}
}
}
5.创建点对点的聊天应用
01.创建服务端
/**
*发送消息线程
*/
class Send extends Thread{
private Socket socket;
public Send(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.sendMsg();
}
/**
* 发送消息
*/
private void sendMsg(){
Scanner scanner = null;
PrintWriter pw = null;
try{
//创建Scanner对象
scanner = new Scanner(System.in);
//创建向对方输出消息的流对象
pw = new PrintWriter(this.socket.getOutputStream());
while(true){
String msg = scanner.nextLine();
pw.println(msg);
pw.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally {
if(scanner != null ){
scanner.close();
}
if(pw != null){
pw.close();
}
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 接收消息的线程
*/
24
class Receive extends Thread{
private Socket socket;
public Receive(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.receiveMsg();
}
/**
* 用于接收对方消息的方法
*/
private void receiveMsg(){
BufferedReader br = null;
try{
//创建用于接收对方发送消息的流对象
br = new BufferedReader(new
InputStreamReader(this.socket.getInputStream()));
while(true){
String msg = br.readLine();
System.out.println("他说:"+msg);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class ChatSocketServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(8888);
System.out.println("服务端启动,等待连接。。。。。");
Socket socket = serverSocket.accept();
System.out.println("连接成功!");
new Send(socket).start();
new Receive(socket).start();
}catch(Exception e){
e.printStackTrace();
}finally{
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
02.创建客户端
/**
*用于发送消息的线程类
*/
class ClientSend extends Thread{
private Socket socket;
public ClientSend(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.sendMsg();
}
/**
*发送消息
*/
private void sendMsg(){
Scanner scanner = null;
PrintWriter pw = null;
try{
//创建Scanner对象
scanner = new Scanner(System.in);
//创建向对方输出消息的流对象
pw = new PrintWriter(this.socket.getOutputStream());
while(true){
String msg = scanner.nextLine();
pw.println(msg);
pw.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally {
if(scanner != null ){
scanner.close();
}
if(pw != null){
pw.close();
}
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 用于接收消息的线程类
*/
class ClientReceive extends Thread{
private Socket socket;
public ClientReceive(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.receiveMsg();
27
}
/**
* 用于接收对方消息的方法
*/
private void receiveMsg(){
BufferedReader br = null;
try{
//创建用于接收对方发送消息的流对象
br = new BufferedReader(new
InputStreamReader(this.socket.getInputStream()));
while(true){
String msg = br.readLine();
System.out.println("他说:"+msg);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class ChatSocketClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 8888);
System.out.println("连接成功!");
new ClientSend(socket).start();
new ClientReceive(socket).start();
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 发送消息线程
*/
class Send1 extends Thread{
private Socket socket;
private Scanner scanner;
public Send1(Socket socket,Scanner scanner){
this.socket = socket;
this.scanner = scanner;
}
@Override
public void run() {
this.sendMsg();
}
/**
* 发送消息
*/
private void sendMsg(){
PrintWriter pw = null;
try{
//创建向对方输出消息的流对象
pw = new PrintWriter(this.socket.getOutputStream());
while(true){
String msg = scanner.nextLine();
pw.println(msg);
pw.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally {
if(scanner != null ){
scanner.close();
}
if(pw != null){
pw.close();
}
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 接收消息的线程
*/
class Receive1 extends Thread{
private Socket socket;
public Receive1(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.receiveMsg();
}
/**
* 用于接收对方消息的方法
*/
private void receiveMsg(){
BufferedReader br = null;
try{
//创建用于接收对方发送消息的流对象
br = new BufferedReader(new
InputStreamReader(this.socket.getInputStream()));
while(true){
String msg = br.readLine();
System.out.println("他说:"+msg);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class GoodTCP {
public static void main(String[] args) {
Scanner scanner = null;
ServerSocket serverSocket = null;
Socket socket = null;
try{
scanner = new Scanner(System.in);
System.out.println("请输入:server, 或者:
,");
String str = scanner.nextLine();
String[] arr = str.split(",");
if("server".equals(arr[0])){
//启动服务端
System.out.println("TCP Server Listen at
"+arr[1]+" .....");
serverSocket = new
ServerSocket(Integer.parseInt(arr[1]));
socket = serverSocket.accept();
System.out.println("连接成功!");
}else{
//启动客户端
socket = new Socket(arr[0],Integer.parseInt(arr[1]));
System.out.println("连接成功!");
}
//启动发送消息的线程
new Send1(socket,scanner).start();
//启动接收消息的线程
new Receive1(socket).start();
}catch(Exception e){
e.printStackTrace();
}finally{
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
03.优化点对点聊天应用
6.一对多应用
01.一对多应用设计
各socket 对间独立问答,互相间不需要传递信息

02.一对多问答型服务器
/**
* 定义消息处理线程类
*/
class Msg extends Thread{
private Socket socket;
public Msg(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.msg();
}
private void msg(){
BufferedReader br = null;
PrintWriter pw = null;
try{
br = new BufferedReader(new
InputStreamReader(this.socket.getInputStream()));
pw = new PrintWriter(this.socket.getOutputStream());
while(true){
pw.println(br.readLine()+" [ok]");
pw.flush();
}
}catch(Exception e){
System.out.println(this.socket.getInetAddress()+" 断线了!");
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(pw != null){
pw.close();
}
}
}
}
public class EchoServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(8888);
while(true){
Socket socket = serverSocket.accept();
new Msg(socket).start();
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
03.一对多聊天服务器
001.服务器设计
0001.服务器的连接设计

0002,服务器的线程设计

04,创建一对多聊天服务应用
/**
* 接收客户端消息的线程类
*/
class ChatReceive extends Thread{
private Socket socket;
public ChatReceive(Socket socket){
this.socket =socket;
}
@Override
public void run() {
this.receiveMsg();
}
/**
* 实现接收客户端发送的消息
*/
private void receiveMsg(){
BufferedReader br = null;
try{
br = new BufferedReader(new
InputStreamReader(this.socket.getInputStream()));
while(true){
String msg = br.readLine();
synchronized ("abc"){
//把读取到的数据写入公共数据区
ChatRoomServer.buf="["+this.socket.getInetAddress()+"] "+msg;
//唤醒发送消息的线程对象。
"abc".notifyAll();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 向客户端发送消息的线程类
*/
class ChatSend extends Thread{
private Socket socket;
public ChatSend(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.sendMsg();
}
/**
* 将公共数据区的消息发送给客户端
*/
private void sendMsg(){
PrintWriter pw = null;
try{
pw = new PrintWriter(this.socket.getOutputStream());
while(true){
synchronized ("abc"){
//让发送消息的线程处于等待状态
"abc".wait();
//将公共数据区中的消息发送给客户端
pw.println(ChatRoomServer.buf);
pw.flush();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pw != null){
pw.close();
}
if(this.socket != null){
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class ChatRoomServer {
//定义公共数据区
public static String buf;
public static void main(String[] args) {
System.out.println("Chat Server Version 1.0");
System.out.println("Listen at 8888.....");
ServerSocket serverSocket =null;
try{
serverSocket = new ServerSocket(8888);
while(true){
Socket socket = serverSocket.accept();
System.out.println("连接到:"+socket.getInetAddress());
new ChatReceive(socket).start();
new ChatSend(socket).start();
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
三,UDP通信的实现
1.UDP通信介绍
UDP协议与之前讲到的TCP协议不同,是面向无连接的,双方不需要建立连接便可通信。UDP通信所发送的数据需要进行封包操作(使用DatagramPacket类),然后才能接收或发送(使用DatagramSocket类)。

DatagramPacket:数据容器(封包)的作用
此类表示数据报包。 数据报包用来实现将发送的数据进行封包处理的。
常用方法:
DatagramPacket(byte[] buf, int length) :构造数据报包,用来指定长度为 length 的数据包。
DatagramPacket(byte[] buf, int length, InetAddress address, int port) :构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
getAddress() :获取发送或接收方计算机的IP地址,此数据报将要发往该机器或者是从该机器接收到的。
getData() :获取发送或接收的数据。
setData(byte[] buf) :设置发送的数据。
DatagramSocket:用于发送或接收数据报包
当客户端要向服务端发送数据时,需要在客户端产生一个DatagramSocket对象,在服务端产生一个DatagramSocket对象。客户端的DatagramSocket将DatagramPacket 发送到网络上,然后被服务端的DatagramSocket接收。
常用方法: DatagramSocket(int port) :创建数据报套接字并将其绑定到本地主机上的指定端口。
send(DatagramPacket p) :从此套接字发送数据报包。
receive(DatagramPacket p) :从此套接字接收数据报包。
close() :关闭此数据报套接字。
UDP通信编程基本步骤:
1. 创建服务器端的DatagramSocket,创建时,定义服务器端的监听端口。
2.创建客户端的DatagramSocket,创建时,定义客户端的监听端口。
3.在服务器端定义DatagramPacket对象,封装待接收的数据包。
4.客户端将数据报包发送出去。
5.服务器端接收数据报包。
2.入门案例
01.创建服务端
public class UDPTest {
public static void main(String[] args) {
DatagramSocket datagramSocket = null;
try{
//创建服务端接收数据的DatagramSocket对象
datagramSocket = new DatagramSocket(9999);
//创建数据缓存区
byte[] b = new byte[1024];
//创建数据报包对象
DatagramPacket dp =new DatagramPacket(b,b.length);
//等待接收客户端所发送的数据
datagramSocket.receive(dp);
String str = new String(dp.getData(),0,dp.getLength());
System.out.println(str);
}catch(Exception e){
e.printStackTrace();
}finally{
if(datagramSocket != null){
datagramSocket.close();
}
}
}
}
02.创建客户端
public class UDPClient {
public static void main(String[] args) {
DatagramSocket ds =null;
try {
//消息需要进行类型转换,转换成字节数据类型。
byte[] b = "北京尚学堂".getBytes();
//创建数据报包装对象DatagramPacket
DatagramPacket dp = new DatagramPacket(b, b.length, new
InetSocketAddress("127.0.0.1", 9999));
//创建数据发送对象DatagramSocket,需要指定消息的发送端口
ds = new DatagramSocket(8888);
//发送消息
ds.send(dp);
}catch(Exception e){
e.printStackTrace();
}finally{
if(ds != null){
ds.close();
}
}
}
}
3.传递基本数据类型
01.创建服务端
public class BasicTypeServer {
public static void main(String[] args) {
DatagramSocket datagramSocket = null;
DataInputStream ds = null;
try{
datagramSocket = new DatagramSocket(9999);
byte[] buf = new byte[1024];
DatagramPacket datagramPacket = new
DatagramPacket(buf,buf.length);
datagramSocket.receive(datagramPacket);
//通过基本数据输入流对象获取传递的数据
ds = new DataInputStream(new
ByteArrayInputStream(datagramPacket.getData()));
System.out.println(ds.readLong());
}catch(Exception e){
e.printStackTrace();
}finally{
if(datagramSocket != null){
datagramSocket.close();
}
if(ds != null){
try {
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
02.创建客户端
public class BasicTypeClient {
public static void main(String[] args) {
long n = 2000L;
ByteArrayOutputStream bos = null;
DataOutputStream dos = null;
DatagramSocket datagramSocket = null;
try{
bos = new ByteArrayOutputStream();
dos = new DataOutputStream(bos);
dos.writeLong(n);
//将基本数据类型数据转换成字节数组类型
byte[] arr = bos.toByteArray();
DatagramPacketdp=newDatagramPacket(arr,arr.length,new
InetSocketAddress("127.0.0.1",9999));
datagramSocket = new DatagramSocket(9000);
datagramSocket.send(dp);
}catch (Exception e){
e.printStackTrace();
}finally{
if(bos != null ){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(dos != null){
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(datagramSocket != null){
datagramSocket.close();
}
}
}
}
4.传递自定义对象类型
01.创建Person类
/**
*当该对象需要在网络上传输时,一定要实现Serializable接口
*/
public class Person implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
02,。创建服务端
public class ObjectTypeServer {
public static void main(String[] args) {
DatagramSocket datagramSocket = null;
ObjectInputStream objectInputStream = null;
try{
datagramSocket = new DatagramSocket(9999);
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
datagramSocket.receive(dp);
//对接收的内容做类型转换
objectInputStream = new ObjectInputStream(new
ByteArrayInputStream(dp.getData()));
System.out.println(objectInputStream.readObject());
}catch(Exception e){
e.printStackTrace();
}finally{
if(datagramSocket != null){
datagramSocket.close();
}
if(objectInputStream != null){
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
03.创建客户端
public class ObjectTypeClient {
public static void main(String[] args) {
DatagramSocket datagramSocket = null;
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
try{
Person p = new Person();
p.setName("Oldlu");
p.setAge(18);
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(p);
byte[] arr = bos.toByteArray();
DatagramPacket dp = new DatagramPacket(arr,arr.length,new
InetSocketAddress("127.0.0.1",9999));
datagramSocket = new DatagramSocket(8888);
datagramSocket.send(dp);
}catch(Exception e){
e.printStackTrace();
}finally{
if(datagramSocket != null ){
datagramSocket.close();
}
if(bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(oos != null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
四,总结
端口是虚拟的概念,并不是说在主机上真的有若干个端口。
在www上,每一信息资源都有统一且唯一的地址,该地址就叫URL(Uniform Resource Locator),它是 www的统一资源定位符。
TCP与UDP的区别
TCP是面向连接的,传输数据安全,稳定,效率相对较低。
UDP是面向无连接的,传输数据不安全,效率较高。
Socket通信是一种基于TCP协议,建立稳定连接的点对点的通信。
网络编程是由java.net包来提供网络功能。
InetAddress:封装计算机的IP地址和DNS(没有端口信息!)。
InetSocketAddress:包含IP和端口,常用于Socket通信。
URL:以使用它的各种方法来对URL对象进行分割、合并等处理。
基于TCP协议的Socket编程和通信
“请求-响应”模式:
Socket类:发送TCP消息。
ServerSocket类:创建服务器。
UDP通讯的实现
DatagramSocket:用于发送或接收数据报包。
常用方法:send()、receive()、 close()。
DatagramPacket:数据容器(封包)的作用
常用方法:构造方法、getAddrress(获取发送或接收方计算机的IP地址)、 getData(获取发送或接收的数据)、setData(设置发送的数据)。
浙公网安备 33010602011771号