Java网络编程笔记
1 IP地址
使用java的类InetAddress
public class TestInetAddress {
public static void main(String[] args) {
try {
//本机地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);
InetAddress inetAddress2 = InetAddress.getByName("localhost");
System.out.println(inetAddress2);
InetAddress inetAddress3 = InetAddress.getLocalHost();
System.out.println(inetAddress3);
//网站地址
InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress4);
//常用方法
System.out.println(inetAddress4.getAddress());
System.out.println(inetAddress4.getCanonicalHostName());
System.out.println(inetAddress4.getHostAddress());
System.out.println(inetAddress4.getHostName());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
2 端口
端口表示计算机上的程序的一个进程
- 0 ~ 65535
- 不同进程不同端口号,不能冲突
- TCP和UDP有各自的端口号,不冲突
public class TestInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress socketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080);
System.out.println(socketAddress1);
System.out.println(socketAddress2);
System.out.println(socketAddress1.getAddress());
System.out.println(socketAddress1.getHostName());
System.out.println(socketAddress1.getPort());
}
}
3 通信协议
- TCP
- 连接,稳定
- 三次握手,四次挥手
- 客户端与服务端之间
- 传输完成,释放连接,效率低
- UDP
- 不连接,不稳定
- 客户端与服务端没有明确的界限
- 不管有没有准备好都可以发送
4 TCP
客户端
- 连接服务器 Socket
- 发送消息
服务端
- 建立服务的端口 ServerSocket
- 等待用户的连接 accept
- 接收消息
//客户端
public class TcpClientDemo {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
//获取服务器的地址,端口号
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
int port = 8888;
//创建socket连接
socket = new Socket(serverIP, port);
//发送消息
os = socket.getOutputStream();
os.write("test connection".getBytes());
} catch (EXception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//服务端
public class TcpServerDemo {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//设定服务器的地址
serverSocket = new ServerSocket(8888);
//等待客户端连接
socket = serverSocket.accept();
//读取客户端的消息
is = socket.getInputStream();
//管道流
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5 TCP实现文件上传
public class TcpClientDemo {
public static void main(String[] args) throws Exception {
//创建Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
//创建输出流
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("test.jpg"));
//写出文件
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//通知服务器传输结束
socket.shutdownOutput();
//确定服务端接收完毕才能断开连接
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int len2;
while ((len2 = is.read(buffer2)) != -1) {
baos.write(buffer2, 0, len2);
}
System.out.println(baos.toString());
//关闭资源
baos.close();
is.close()
fis.close();
os.close();
socket.close();
}
}
public class TcpServerDemo {
public static void main(String[] args) throws Exception {
//创建端口
ServerSocket serverSocket = new ServerSocket(9999);
//监听客户端连接
Socket socket = serverSocket.accept(); //阻塞式监听,会一直等待客户端连接
//获取输入流
InputStream is = socket.getInputStream();
//文件输出
FileOutputStream fos = new FileOutputSteam(new File("receive.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
//通知客户端接收完毕
OutputStream os = socket.getOutputStream();
os.write("over".getBytes());
//关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
6 UDP
UDP没有客户端和服务端区分,这里只是方便显示
public class UdpClientDemo {
public static void main(String[] args) throws Exception {
//建立Socket
DatagramSocket socket = new DatagramSocket();
//建个包
String msg = "test";
InetAddress ip = InetAddress.getByName("127.0.0.1");
int port = 9000;
//数据,数据长度,接收方ip和端口
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, ip, port);
//发送包
socket.send(packet);
//关闭资源
socket.close();
}
}
public class UdpServerDemo {
public static void main(String[] args) {
//开放端口
DatagramSocket socket = new DatagramSocket(9000);
//接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(), 0, packet.getLength()));
//关闭资源
socket.close();
}
}
7 UDP实现聊天
public class UdpSenderDemo {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
//准备数据,控制台读取System.in
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("127.0.0.1", 9999));
socket.send(packet);
if (data.trim().equals("bye")) {
break;
}
}
socket.close();
}
}
public class UdpReceiveDemo {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9999);
while (true) {
//准备接收数据
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
socket.receive(packet);
//断开连接
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(receiveData);
if (receiveData.trim().equals("bye")) {
break;
}
}
}
}
如果要实现发送的同时可以接收信息,那么双方都要建立两个线程,一个负责发送,一个负责接收
8 URL
统一资源定位符
- 协议://ip地址:端口/项目名/资源
public class URLDemo {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://localhost:8080/test/index.html?a=1&b=2");
System.out.println(url.getProtocol()); //协议
System.out.println(url.getHost()); //主机ip
System.out.println(url.getPort()); //端口
System.out.println(url.getPath()); //文件
System.out.println(url.getFile()); //全路径
System.out.println(url.getQuery()); //参数
}
}
利用URL下载网络资源
public class URLDownload {
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:8080/test/test.txt");
//连接到资源
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream is = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("receive.txt");
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
is.close();
urlConnection.close();
}
}