,java.net包中.
获取百度IP
import java.net.InetAddress; import java.net.UnknownHostException; class IPDemo { public static void main(String[] args) throws UnknownHostException { InetAddress ia = InetAddress.getByName("www.baidu.com"); System.out.println(ia.getHostAddress()); } }
java.net 包中
构造方法:其他参与API.
常用方法:
void send(DatagramPacket p)java.net 包中
构造方法:import java.net.*; class UdpSend { public static void main(String[] args) throws Exception { // 1、创建udp服务。通过DatagramSocket对象。 DatagramSocket ds = new DatagramSocket(8888); // 2、确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress // address, int port) byte[] buf = "udp ge men lai le ".getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.254"), 10000); // 3、通过socket服务,将已有的数据包发送出去。通过send方法。 ds.send(dp); // 4、关闭资源。 ds.close(); } }
import java.net.*; class UdpRece { public static void main(String[] args) throws Exception { // 1、创建udp socket,建立端点。 DatagramSocket ds = new DatagramSocket(10000); while (true) { // 2、定义数据包。用于存储数据。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); // 3、通过服务的receive方法将收到数据存入数据包中。 ds.receive(dp);// 阻塞式方法。 // 4、通过数据包的方法获取其中的数据。 String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(), 0, dp.getLength()); int port = dp.getPort(); System.out.println(ip + "::" + data + "::" + port); } // 5、关闭资源 // ds.close(); } }
编写一个聊天程序
/* 编写一个聊天程序。 有收数据的部分,和发数据的部分。 这两部分需要同时执行。 那就需要用到多线程技术。 一个线程控制收,一个线程控制发。 因为收和发动作是不一致的,所以要定义两个run方法。 而且这两个方法要封装到不同的类中。 */ import java.net.*; import java.io.*; class Send implements Runnable// 发送端 { private DatagramSocket ds; public Send(DatagramSocket ds) { this.ds = ds; } public void run()// 多线程覆盖run方法 { try { // 键盘录入 BufferedReader bufr = new BufferedReader(new InputStreamReader( System.in)); String len = null; while ((len = bufr.readLine()) != null) { // 转换成字节数组发送数据 byte[] buf = len.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 10001); ds.send(dp); if ("886".equals(len)) break; } } catch (Exception e) { throw new RuntimeException("发送端失败"); } } } class Rece implements Runnable// 接收端 { private DatagramSocket ds; public Rece(DatagramSocket ds) { this.ds = ds; } public void run() { try { while (true) { // 建立字节数组接收数据 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); // 获取IP String ip = dp.getAddress().getHostAddress(); // 将包转化成字符串 String data = new String(dp.getData(), 0, dp.getLength()); if ("886".equals(data)) { System.out.println(ip + "...离开聊天室"); break; } // 打印 System.out.println(ip + ".," + data); } } catch (Exception e) { throw new RuntimeException("接收端失败"); } } } class ChatDemo { public static void main(String[] args) throws Exception { // 创建接收端和发送端 DatagramSocket sendSocket = new DatagramSocket(); DatagramSocket receSocket = new DatagramSocket(10001); // 开启多线程 new Thread(new Send(sendSocket)).start(); new Thread(new Rece(receSocket)).start(); } }
返回此套接字的输出流。
InputStream getInputStream()import java.io.*; import java.net.*; class TcpClient// 客户端 { public static void main(String[] args) throws Exception { // 创建客户端的socket服务。指定目的主机和端口 Socket s = new Socket("127.0.0.1", 10003); // 为了发送数据,应该获取socket流中的输出流。 OutputStream out = s.getOutputStream(); out.write("tcp ge men lai le ".getBytes()); s.close(); } }
import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; class TcpServer// 服务端 { public static void main(String[] args) throws Exception { // 建立服务端socket服务。并监听一个端口。 ServerSocket ss = new ServerSocket(10003); // 通过accept方法获取连接过来的客户端对象。 while (true) { Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + ".....connected"); // 获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf, 0, len)); s.close();// 关闭客户端. } // ss.close(); } }
/* 需求:建立一个文本转换服务器。 客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。 而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。 分析: 客户端: 既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。 源:键盘录入。 目的:网络设备,网络输出流。 而且操作的是文本数据。可以选择字符流。 步骤 1、建立服务。 2、获取键盘录入。 3、将数据发给服务端。 4、后去服务端返回的大写数据。 5、结束,关资源。 都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲。 */ import java.io.*; import java.net.*; class TransClient { public static void main(String[] args) throws Exception { Socket s = new Socket("127.0.0.1", 10005); // 定义读取键盘数据的流对象。 BufferedReader bufr = new BufferedReader(new InputStreamReader( System.in)); // 定义目的,将数据写入到socket输出流。发给服务端。 PrintWriter out = new PrintWriter(s.getOutputStream(), true); // 定义一个socket读取流,读取服务端返回的大写信息。 BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); String line = null; while ((line = bufr.readLine()) != null) { if ("over".equals(line)) break; out.println(line); String str = bufIn.readLine(); System.out.println("server:" + str); } bufr.close(); s.close(); } } /* * 服务端: 源:socket读取流。 目的:socket输出流。 都是文本,装饰。 */ class TransServer { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(10005); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "....connected"); // 读取socket读取流中的数据。 BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); // 目的。socket输出流。将大写数据写入到socket输出流,并发送给客户端。 PrintWriter out = new PrintWriter(s.getOutputStream(), true); String line = null; while ((line = bufIn.readLine()) != null) { System.out.println(line); out.println(line.toUpperCase()); } s.close(); ss.close(); } }
import java.io.*; import java.net.*; class TextClient { public static void main(String[] args) throws Exception { // 建立服务端socket服务。并监听一个端口。 Socket s = new Socket("127.0.0.1", 10006); // 和指定文件关联 BufferedReader bufr = new BufferedReader(new FileReader("IPDemo.java")); // 发出数据 PrintWriter out = new PrintWriter(s.getOutputStream(), true); String line = null; while ((line = bufr.readLine()) != null) { out.println(line); } s.shutdownOutput();// 关闭客户端的输出流。相当于给流中加入一个结束标记-1. // 接收服务端返回的数据 BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); String str = bufIn.readLine(); System.out.println(str); bufr.close(); s.close(); } } class TextServer { public static void main(String[] args) throws Exception { // 服务端 ServerSocket ss = new ServerSocket(10006); Socket s = ss.accept(); // 获取并打印IP String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "....connected"); // 接收客户端的数据 BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); // 服务端输出目的 PrintWriter out = new PrintWriter(new FileWriter("server.txt"), true); String line = null; while ((line = bufIn.readLine()) != null) { // if("over".equals(line)) // break; out.println(line); } // 告诉客户端上传成功 PrintWriter pw = new PrintWriter(s.getOutputStream(), true); pw.println("上传成功"); out.close(); s.close(); ss.close(); } }
/* 客户端。 1、服务端点。 2、读取客户端已有的图片数据。 3、通过socket 输出流将数据发给服务端。 4、读取服务端反馈信息。 5、关闭。 */ import java.io.*; import java.net.*; class PicClient { public static void main(String[] args) throws Exception { // 对传进来的文件进行多重判断 if (args.length != 1) { System.out.println("请选择一个jpg格式的图片"); return; } File file = new File(args[0]); if (!(file.exists() && file.isFile())) { System.out.println("该文件有问题,要么补存在,要么不是文件"); return; } if (!file.getName().endsWith(".jpg")) { System.out.println("图片格式错误,请重新选择"); return; } if (file.length() > 1024 * 1024 * 5) { System.out.println("文件过大,没安好心"); return; } // 建立Socket服务,往服务端发送数据 Socket s = new Socket("127.0.0.1", 10007); // 建立字节流和文件相关联 FileInputStream fis = new FileInputStream(file); // 使用Socket输出方法网服务端写出数据 OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while ((len = fis.read(buf)) != -1) { out.write(buf, 0, len); } // 告诉服务端数据已写完 s.shutdownOutput(); // 使用Socket输出方法网服务端接收数据 InputStream in = s.getInputStream(); byte[] bufIn = new byte[1024]; int num = in.read(bufIn); System.out.println(new String(bufIn, 0, num)); fis.close(); s.close(); } }
/* 服务端 这个服务端有个局限性。当A客户端连接上以后。被服务端获取到。服务端执行具体流程。 这时B客户端连接,只有等待。 因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法。所以 暂时获取不到B客户端对象。 那么为了可以让多个客户端同时并发访问服务端。 那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。 如何定义线程呢? 只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。 */ class PicThread implements Runnable { // 传进来的客户端 private Socket s; PicThread(Socket s) { this.s = s; } // 对现场的Run方法 public void run() { // 定义计数器,为了不让存入的文件相同 int count = 1; // 获取客户端连进来的IP String ip = s.getInetAddress().getHostAddress(); try { // 打印客户端IP System.out.println(ip + "....connected"); // 接收客户端传来的图片 InputStream in = s.getInputStream(); // 创建了路径.并存入格式比如 127.0.0.1(1).jpg File dir = new File("d:\\pic"); File file = new File(dir, ip + "(" + (count) + ")" + ".jpg"); // 如果文件存在的话就用while循环判断文件是否存在.知道不存在添加 while (file.exists()) file = new File(dir, ip + "(" + (count++) + ")" + ".jpg"); // 输出 FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[1024]; int len = 0; while ((len = in.read(buf)) != -1) { fos.write(buf, 0, len); } // 告诉客户端上传成功 OutputStream out = s.getOutputStream(); out.write("上传成功".getBytes()); fos.close(); s.close(); } catch (Exception e) { throw new RuntimeException(ip + "上传失败"); } } } class PicServer// 服务端 { public static void main(String[] args) throws Exception { // 接收客户端传来的数据 ServerSocket ss = new ServerSocket(10007); while (true) { // 阻塞是方法 Socket s = ss.accept(); // 为了实现多台客户端同时上传图片使用多线程 new Thread(new PicThread(s)).start(); } // ss.close(); } }
/* 客户端通过键盘录入用户名。 服务端对这个用户名进行校验。 如果该用户存在,在服务端显示xxx,已登陆。 并在客户端显示 xxx,欢迎光临。 如果该用户存在,在服务端显示xxx,尝试登陆。 并在客户端显示 xxx,该用户不存在。 最多就登录三次。 */ import java.io.*; import java.net.*;//导入包 class LoginClient// 客户端 { public static void main(String[] args) throws Exception { // 建立客户端 Socket s = new Socket("192.168.1.254", 10008); // 键盘录入 BufferedReader bufr = new BufferedReader(new InputStreamReader( System.in)); // 定义目的,将数据写入到socket输出流。发给服务端。 PrintWriter out = new PrintWriter(s.getOutputStream(), true); // 接收服务端返回的数据 BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); // for循环,因为最多可以登录3次. for (int x = 0; x < 3; x++) { // 将键盘录入的字符,转换成字符串,并判断是否是空.如果是直接退出,如果不是传个服务端 String line = bufr.readLine(); if (line == null) break; out.println(line); // 接收并打印服务端返回的数据.判断是否返回的是"欢迎". String info = bufIn.readLine(); System.out.println("info:" + info); if (info.contains("欢迎")) break; } // 关闭流 bufr.close(); s.close(); } } class UserThread implements Runnable { // 接收传进来的客户端 private Socket s; UserThread(Socket s) { this.s = s; } public void run() { // 获取并打印客户端的IP String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "....connected"); try { // 最多就登录三次。用for训话 for (int x = 0; x < 3; x++) { // 接收客户端传来的数据 BufferedReader bufIn = new BufferedReader( new InputStreamReader(s.getInputStream())); // 判断传进来的数据是否为空 String name = bufIn.readLine(); if (name == null) break; // 建立字符输入流和文件相关联, BufferedReader bufr = new BufferedReader(new FileReader( "user.txt")); // 建立给客户端的传输的数据 PrintWriter out = new PrintWriter(s.getOutputStream(), true); String line = null; // 定义一个布尔型变量,来判断用户是否存在 boolean flag = false; // 循环,并判断客户端传进来的数据.和服务端的数据是否相同. // 如果是退出循环,并显示xxx.已登录,和返回给客户端"xxx欢迎光临" // 如果输入不是在服务端显示XXX尝试登陆,并返回给客户端xxxz用户名不存在 while ((line = bufr.readLine()) != null) { if (line.equals(name)) { flag = true; break; } } if (flag) { System.out.println(name + ",已登录"); out.println(name + ",欢迎光临"); break; } else { System.out.println(name + ",尝试登录"); out.println(name + ",用户名不存在"); } } s.close(); } // 异常处理 catch (Exception e) { throw new RuntimeException(ip + "校验失败"); } } } class LoginServer { public static void main(String[] args) throws Exception { // 服务端 ServerSocket ss = new ServerSocket(10008); while (true) { // 阻塞式方法 Socket s = ss.accept(); // 建立多线程,因为N多的服务端要访问 new Thread(new UserThread(s)).start(); } } }