Socket
网络编程
查询ip
import java.net.InetAddress;
import java.net.UnknownHostException;
public class MyInetAddress {
public static void main(String[] args) {
try {
// 查询本机地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1"); // /127.0.0.1
System.out.println(inetAddress1);
InetAddress inetAddress2 = InetAddress.getByName("localhost"); // localhost/127.0.0.1
System.out.println(inetAddress2);
InetAddress inetAddress3 = InetAddress.getLocalHost(); // JSSM-20210706VO/192.168.40.167
System.out.println(inetAddress3);
// 查询网站ip地址
InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com"); // www.baidu.com/180.101.49.11
System.out.println(inetAddress4);
// 常用方法
System.out.println(inetAddress4.getAddress()); // [B@4783da3f
System.out.println(inetAddress4.getCanonicalHostName()); // 180.101.49.11
System.out.println(inetAddress4.getHostAddress()); // 180.101.49.11
System.out.println(inetAddress4.getHostName()); // www.baidu.com
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
查询端口
-
不同进程有不同的端口号,用来区分软件
-
0~65535
-
TCP、UDP:65535*2。单个协议下端口号不能冲突
-
公有端口:1~1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
-
程序注册端口:1024~49151
- Tomcat:8080
- MySQL:3306
- Oracle:1521
-
动态、私有端口:49151~65535
- netstat -ano:查看所有端口
import java.net.InetSocketAddress;
public class MySocketAddress {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);
System.out.println(inetSocketAddress1); // /127.0.0.1:8080
System.out.println(inetSocketAddress2); // localhost/127.0.0.1:8080
System.out.println(inetSocketAddress1.getAddress()); // /127.0.0.1
System.out.println(inetSocketAddress1.getHostName()); // 127.0.0.1
System.out.println(inetSocketAddress1.getPort()); // 8080
}
}
TCP
普通版
- MyServer.java
package demo;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) {
ServerSocket serverSocket = null; // 新建ServerSocket对象
Socket socket = null; // 接收客户端连接
InputStream is = null; // 用于读取客户端消息
OutputStream os = null;
ByteArrayOutputStream baos = null;
try {
// 1.创建指定端口的连接
serverSocket = new ServerSocket(9999);
while (true){
// 2.监听 没有连接就阻塞在此
socket = serverSocket.accept();
// 3.从socket取出来自客户端的数据
is = socket.getInputStream();
// 解析数据
// 方法一
/* baos = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len;
while ((len=is.read(buff))!=-1){
baos.write(buff,0,len);
}
System.out.println(baos);*/
// 方法二
InputStreamReader reader = new InputStreamReader(is);
BufferedReader bufReader = new BufferedReader(reader);
String s;
StringBuffer sb = new StringBuffer();
while ((s = bufReader.readLine()) != null) {
sb.append(s);
}
System.out.println("服务器:" + sb);
// 关闭输入流
socket.shutdownInput();
// 4.向socket写入数据,发送给客户端
os = socket.getOutputStream();
os.write(("服务端返回给客户端的信息").getBytes());
os.flush(); // 强制将缓冲区中的数据发送出去,不必等到缓冲区满
// 关闭输出流
socket.shutdownOutput();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
/**
* 在使用TCP编程的时候,最后需要释放资源,关闭socket(socket.close());
* 关闭socket输入输出流(socket.shutdownInput()以及socket.shutdownOutput());关闭IO流(is.close() os.close())。
* 需要注意的是:关闭socket的输入输出流需要放在关闭Io流之前。
* 因为关闭IO流会同时关闭socket,一旦关闭了socket的,就不能再进行socket的相关操作了。
* 而只关闭socket输入输出流(socket.shutdownInput()以及socket.shutdownOutput())不会完全关闭socket,此时任然可以进行socket方面的操作。
* 所以要先调用socket.shutdownXXX,然后再调用io.close();
*/
if(baos != null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null){
try {
is.close(); // 关闭IO流会同时关闭socket
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
socket.shutdownOutput();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
// 关闭socket
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket != null){
try {
// 关闭serverSocket
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- MyClient.java
package demo;
import java.io.*;
import java.net.Socket;
public class MyClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
// 1.创建socket连接
socket = new Socket("127.0.0.1", 9999);
// 2.向socket写入数据,发送给服务端
// 2.1发送文字
/* os = socket.getOutputStream();
os.write("客户端发送给服务端的信息".getBytes());
os.flush();
// 关闭输出流
socket.shutdownOutput();*/
// 2.2发送图片
os = socket.getOutputStream();
// 读取文件
FileInputStream fis = new FileInputStream(new File("haha.jpg"));
// 写出文件到输出流中
byte[] buffer = new byte[1024];
int len;
while ((len=fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
os.flush();
socket.shutdownOutput();
// 3.从socket取出来自服务端的数据
InputStream is = socket.getInputStream();
// 解析服务器返回的数据
InputStreamReader reader = new InputStreamReader(is);
BufferedReader bufReader = new BufferedReader(reader);
String s;
final StringBuffer sb = new StringBuffer();
while ((s = bufReader.readLine()) != null) {
sb.append(s);
}
System.out.println(sb);
// 关闭输入流
socket.shutdownInput();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.释放所有资源
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
多线程版
- MyServerThread.java把socket封装在Thread内部
package multipleservice;
import java.io.*;
import java.net.Socket;
public class MyServerThread extends Thread {
private Socket socket;
public MyServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
super.run();
InputStream is = null; // 用于读取客户端消息
OutputStream os = null;
ByteArrayOutputStream baos = null;
try {
// 1.从socket取出来自客户端的数据
is = socket.getInputStream();
// 2.解析数据
// 2.1接受文字
// 方法一
/* baos = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len;
while ((len=is.read(buff))!=-1){
baos.write(buff,0,len);
}
System.out.println(baos);*/
// 方法二
/* InputStreamReader reader = new InputStreamReader(is);
BufferedReader bufReader = new BufferedReader(reader);
String s;
StringBuffer sb = new StringBuffer();
while ((s = bufReader.readLine()) != null) {
sb.append(s);
}
System.out.println("服务器:" + sb);
// 关闭输入流
socket.shutdownInput();*/
// 2.2接受图片
FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
socket.shutdownInput();
// 3.向socket写入数据,发送给客户端
os = socket.getOutputStream();
os.write(("服务端返回给客户端的信息").getBytes());
os.flush();
// 关闭输出流
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放所有资源
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close(); // 关闭IO流会同时关闭socket
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
// 关闭socket
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- MyMultiThreadServer.java
package multipleservice;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MyMultiThreadServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
// 1.新建serverSocket对象并指定端口
serverSocket = new ServerSocket(9999);
// 2.不停的监听客户端
while (true) {
System.out.println("监听客户端ing");
// accept方法会阻塞,直到有客户端与之建立连接
Socket socket = serverSocket.accept();
// 将socket放到子线程中
new MyServerThread(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 3.释放资源
if (serverSocket != null) {
try {
// 关闭serverSocket
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
UDP
package ip;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//还是要等待客户端的连接
public class UdpServer {
public static void main(String[] args) throws Exception{
//开放端口
DatagramSocket datagramSocket = new DatagramSocket(9090);
//接收数据包
byte[] buffer = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(buffer, 0, buffer.length);
datagramSocket.receive(datagramPacket);//阻塞接收
System.out.println(datagramPacket.getAddress());
System.out.println(new String(datagramPacket.getData(), 0, datagramPacket.getLength()));
datagramSocket.close();
}
}