Socket简介:
Socket称为“套接字”,描述IP地址和端口。在Internet上的主机一般运行多个服务软件,同时提供几种服务,每种服务都打开一个Socket,并绑定在一个端口上,不同的端口对应于不同的服务。Socket和ServerSocket类位于java.net包中。ServerSocket用于服务端,Socket是建立网络连接时使用的。连接成功时,应用程序两端都会产生一个Socket实例,通过操作这个实例完成所需会话。
Socket常用方法:
-int getLocalPort() 获取本地使用的端口号
-InetAddress getLocalAddress() 获取套接字绑定的本地地址
-int getPort() 获取远端使用的端口号
-InetAddress.getInetAddress() 获取套接字绑定的远端地址
InetAddress常用方法:
-String getCanonicalHostName() 获取此IP地址的完全限定域名。
-String getHostAddress() 返回IP地址字符串
1 //获取本地地址和端口号: 2 public void testSocket() throws Exception{ 3 Socket socket=new Socket("localhost",8088); 4 InetAddress add=socket.getLocalAddress(); 5 System.out.println(add.getCanonicalHostName()); 6 System.out.println(add.getHostName()); 7 System.out.println(add.getLocalPort()); 8 }
1 //获取远端地址和端口号: 2 public static void testSocket() throws Exception{ 3 Socket socket=new Socket("localhost",8088); 4 InetAddress inetAdd=socket.getInetAddress(); 5 System.out.println(inetAdd.getCanonicalHostName()); 6 System.out.println(inetAdd.getHostName()); 7 System.out.println(socket.getLocalPort()); 8 }
其他方法的使用:
package com.demo.inet; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; public class InetAddressDemo { public static void main(String[] args) { // 创建一个字节数组byte 127 ~ -128 byte bt[] = {-64,-88,3,44};//192.168.3.44 try { // 创建InetAddress对象 InetAddress id = InetAddress.getByAddress(bt); System.out.println(id); // 返回原始IP地址 byte[] bs = id.getAddress(); System.out.println(Arrays.toString(bs)); // 返回对象对应IP地址 System.out.println(id.getHostAddress()); // 返回全名计算名称 System.out.println(id.getCanonicalHostName()+"------------------"); // 返回本机计算机名及对应ip地址 System.out.println(InetAddress.getLocalHost()); // 返回host名称对应域名及ip地址 InetAddress[] allByName = InetAddress.getAllByName("www.baidu.com"); System.out.println(Arrays.toString(allByName)); System.out.println(allByName[0].getHostName()); // 域名 System.out.println(allByName[0].getHostAddress()); // ip地址 // 同主机名称获取IP信息 InetAddress addr = InetAddress.getByName("localhost"); System.out.println(addr.getHostAddress()); System.out.println(addr.getCanonicalHostName()); // 返回ip地址 } catch (UnknownHostException e) { e.printStackTrace(); } } }
获取网络输入流和网络输出流
通过Socket获取输入流与输出流,主要使用一下两个方法
-InputStream getInputStream() 用于返回此套接字的输入流
-OutStream getOutputStream() 用于返回此套接字的输出流
public static void testSocket() throws Exception { Socket socket = new Socket("localhost", 8088); OutputStream out = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8"); PrintWriter pw = new PrintWriter(osw, true); pw.println("输出的内容");//发送内容 InputStream in=socket.getInputStream(); InputStreamReader isr=new InputStreamReader(in, "UTF-8"); BufferedReader br=new BufferedReader(isr); br.readLine();//读取接到的内容 }
注意:当使用完Socket进行通讯完毕后,要关闭Socket以释放系统资源
-void close() 关闭套接字,同时也代表关闭了获取的输入与输出流。
服务端ServerSocket监听
1 //创建ServerSocket并申请服务端口8088 2 ServerSocket server=new ServerSocket(8088); 3 /*方法会产生阻塞,直到某个Socket连接,并返回请求连接的Socket*/ 4 Socket socket=server.accept(); 5 ...
客户端Socket连接
1 //参数1:服务端的IP地址,参数2:服务端的服务器端口 2 //注意:创建Socket的同时就会发起连接,若连接失败会抛出异常 3 Socket socket=new Socket("localhost",8088); 4 ....
C-S端通信模型
详细实例演示
Server:
package com.demo.server; import java.io.BufferedOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Server { static int port = 12345; public static void main(String[] args) { // 创建服务端Socket对象 ServerSocket serverSocket = null; while (true) { try { // 创建服务端Socket对象 serverSocket = new ServerSocket(port); System.out.println("等待客户端连接服务器......."); // 阻塞服务器 Socket socket = serverSocket.accept(); System.out.println("客户端连接到服务器......."); // 创建文件输出流 BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream()); os.write("服务器端: 我收到了客户端连接请求。".getBytes()); os.flush(); os.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (serverSocket != null) { serverSocket.close(); } } catch (IOException e) { e.printStackTrace(); } } } } }
Client:
package com.demo.client; import java.io.BufferedInputStream; import java.io.IOException; import java.net.Socket; public class Client { static int port = 12345; static String host = "111.231.93.134"; public static void main(String[] args) { // 创建客户端对象 Socket socket = null; try { // 创建客户端对象 socket = new Socket(host, port); // 获取输入流对象 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); // 定义缓冲字节数组 byte[] buffer = new byte[1024]; // 定义接收实际长度 int len = 0; while ((len = bis.read(buffer)) != -1) { String content = new String(buffer, 0, len); System.out.println("客户端接收的内容:"+content); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
TCP与UDP的区别
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。聊天工具使用TCP协议
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去! 游戏多使用UDP协议
UDP程序演示:
Server:
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /* * 服务器端,实现基于UDP的用户登陆 */ public class UDPServer { public static void main(String[] args) throws IOException { /* * 接收客户端发送的数据 */ // 1.创建服务器端DatagramSocket,指定端口 DatagramSocket socket = new DatagramSocket(8800); // 2.创建数据报,用于接收客户端发送的数据 byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小 DatagramPacket packet = new DatagramPacket(data, data.length); // 3.接收客户端发送的数据 System.out.println("****服务器端已经启动,等待客户端发送数据"); socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞 // 4.读取数据 String info = new String(data, 0, packet.getLength()); System.out.println("我是服务器,客户端说:" + info); /* * 向客户端响应数据 */ // 1.定义客户端的地址、端口号、数据 InetAddress address = packet.getAddress(); int port = packet.getPort(); byte[] data2 = "欢迎您!".getBytes(); // 2.创建数据报,包含响应的数据信息 DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port); // 3.响应客户端 socket.send(packet2); // 4.关闭资源 socket.close(); } }
Client:
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /* * 客户端 */ public class UDPClient { public static void main(String[] args) throws IOException { /* * 向服务器端发送数据 */ // 1.定义服务器的地址、端口号、数据 InetAddress address = InetAddress.getByName("localhost"); int port = 8800; byte[] data = "用户名:admin;密码:123".getBytes(); // 2.创建数据报,包含发送的数据信息 DatagramPacket packet = new DatagramPacket(data, data.length, address, port); // 3.创建DatagramSocket对象 DatagramSocket socket = new DatagramSocket(); // 4.向服务器端发送数据报 socket.send(packet); /* * 接收服务器端响应的数据 */ // 1.创建数据报,用于接收服务器端响应的数据 byte[] data2 = new byte[1024]; DatagramPacket packet2 = new DatagramPacket(data2, data2.length); // 2.接收服务器响应的数据 socket.receive(packet2); // 3.读取数据 String reply = new String(data2, 0, packet2.getLength()); System.out.println("我是客户端,服务器说:" + reply); // 4.关闭资源 socket.close(); } }