建议先学计算机网络原理
网络编程
所有的资料来源都是以【狂神说Java】网络编程实战讲解 为基础
【狂神说Java】网络编程实战讲解
建议看视频,这篇博客是笔记
1.IP
本地:127.0.0.1 :localhost
2.端口
-
公有端口0~1023
- HTTP:80
- HTTPS: 443
- FTP:21
- Telnet: 23
-
程序注册端口: 1024~49151,分配用户或者程序
- Tomcat : 8080
- MySQL : 3306
- Oracle : 1521
-
动态
私有: 49152~ 65535
netstat -ano #查看所有端口
netstat - ano|findstr "5900" #查看指定的端口
tasklist|findstr "8696" #查看指定端口的进程
常用方法:InetSocketAddress
3.TCP
主要注意IO流的操作
客户端
- 连接服务器Socket
- 发送消息
服务器
- 建立服务的端口ServerSocket
- 等待用户的链接accept
- 接收用的消息
重点学习:
Socket类
信息传输
- 客户端代码
package cn.livorth.wangluo;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TestClientDemo01 {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
//获取服务器端口与端口号
InetAddress serverIp = InetAddress.getByName("127.0.0.1");
int port = 9999;
//创建socket连接
socket = new Socket(serverIp, port);
//创建消息IO流
os = socket.getOutputStream();
os.write("你好,世界!hello,world!".getBytes());
} catch (IOException 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();
}
}
}
}
}
- 服务端代码
package cn.livorth.wangluo;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServerDemo01 {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//创建一个带端口的地址
serverSocket = new ServerSocket(9999);
//等待客户端的连接
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();
}
}
}
}
}
- 结果:
文件上传
与前面的文字上传一致
但是要转换为file传输
然后要实现3次握手
客户端代码:
package cn.livorth.wangluo;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TestClientDemo02 {
public static void main(String[] args) throws Exception {
//连接服务器
InetAddress serverIp = InetAddress.getByName("127.0.0.1");
int port = 9000;
Socket socket = new Socket(serverIp, port);
OutputStream os = socket.getOutputStream();
//读取取文件
FileInputStream fis = new FileInputStream(new File("pic01.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());
}
}
服务端代码:
package cn.livorth.wangluo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServerDemo02 {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(9000);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("re.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("接收完毕,可以断开连接".getBytes());
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
结果:
4.UDP
重点学习这个:
DatagramSocket类
类似于发短信,将数据包发送出去,不用管是否接收到
聊天教室实现
发送代码
package cn.livorth.wangluo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class TalkSend implements Runnable{
DatagramSocket socket = null;
BufferedReader reader = null;
private int fromPort;
private String toIP;
private int toPort;
public TalkSend(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
//初始化建立连接
socket = new DatagramSocket(fromPort);
//控制台获取输入的文字信息
reader = new BufferedReader(new InputStreamReader(System.in));
}
catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
//无限循环获取消息
while (true)
{
try {
//读取数据
String data = reader.readLine();
//新建数据包
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));
//发送包
socket.send(packet);
if(data.startsWith("bye"))
break;
} catch (Exception e) {
e.printStackTrace();
}
}
socket.close();
}
}
接收代码:
package cn.livorth.wangluo;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class TalkReceive implements Runnable{
DatagramSocket socket = null;
private int port;
private String msgFrom;
public TalkReceive(int port, String msgFrom) {
this.port = port;
this.msgFrom = msgFrom;
try {
//初始化建立连接
socket = new DatagramSocket(port);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
//无限循环获取消息
while (true){
try {
byte[] container = new byte[1024];
//新建包用于存储等下要接收的信息
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//存储到packet里面
socket.receive(packet);
//转换
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(msgFrom + ":" + receiveData);
if(receiveData.startsWith("bye")){
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
socket.close();
}
}
创建老师和学生用于发送接收信息
老师
package cn.livorth.wangluo;
public class TalkTeacher {
public static void main(String[] args) {
//自己应用端口5555,用8888端口发送
new Thread(new TalkSend(5555, "localhost", 8888)).start();
//接收来自9999端口的学生消息
new Thread(new TalkReceive(9999, "学生")).start();
}
}
学生
package cn.livorth.wangluo;
public class TalkStudent {
public static void main(String[] args) {
//自己应用端口7777,用9999端口发送
new Thread(new TalkSend(7777, "localhost", 9999)).start();
//接收来自8888端口的老师消息
new Thread(new TalkReceive(8888, "老师")).start();
}
}
5.URL
统一资源定位符
URL的相关方法