网络编程
概述
-
计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
-
网络编程的目的
传播交流选项,数据交换,通信
-
需要什么
- 如何准确定位网络上的主机:地址 192.168.XXX.XXX :端口 然后定位到这个计算机上的某个资源
- 如何传输数据:硬件的数据交换
网络通信的要素
-
通信双方的地址:
- ip
- 端口号
- 192.168.XXX.XXX :端口
-
规则:网络通信协议
IP
-
查询IP地址方法:InetAddress类 java.net包下的
-
IP地址能定位到唯一的一台计算机
-
127.0.0.1 本机地址
-
ip地址分类
-
IPV4/IPV6
-
IPV4 127.0.0.1 4个 字节组成 , 0-255 总共42亿 已用尽
-
IPV6 128位 8个无符号整数(16进制)
例如 0000:1111:2222:3456:aaaa:bbbb:cccc:defg
-
-
公网(互联网)-私网(局域网)
- ABCD类
- 192.168.xxx.xxx
-
-
-
InetAddress类常用方法
package com.taodou;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddress {
public static void main(String[] args) {
try {
//查询本机地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
InetAddress inetAddress2 = InetAddress.getByName("LocalHost");
InetAddress inetAddress3 = InetAddress.getLocalHost();
System.out.println(inetAddress1);
System.out.println(inetAddress2);
System.out.println(inetAddress3);
System.out.println("------------------------------------");
//查询网址IP地址
InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress4);
System.out.println(inetAddress4.getCanonicalHostName());//规范名
System.out.println(inetAddress4.getHostAddress());//IP
System.out.println(inetAddress4.getHostName());//域名或主机名
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
端口
端口表示计算机上的一个程序的进程
- 不同的进程有不同的端口号
- 端口号 0~65536
- 端口号有两种TCP,UDP 65536*2 单协议下端口号不能冲突
- 端口分类
- 公有端口(系统程序)0~1023
- HTTP:80
- HTTPS:443
- FTP:21
- 程序注册端口1024~49151
- Tomcat : 8080
- MySQL:3306
- 动态,私有 49152~65536
- 公有端口(系统程序)0~1023
package com.taodou;
import java.net.InetSocketAddress;
public class TestInetSocketAddress {
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);
System.out.println(inetSocketAddress2);
System.out.println(inetSocketAddress1.getAddress());
System.out.println(inetSocketAddress1.getHostName());
System.out.println(inetSocketAddress1.getPort());
}
}
通信协议
一些网络通信时的规范
网络通信协议:速率,传输码率,代码结构
TCP/IP协议集
重要:
- TCP:用户传输协议
- UDP:用户数据报协议
- IP:网络互连协议
TCP与UDP
TCP:约等于打电话
- 连接,稳定
- 三次握手(连接),四次挥手(断开)
- 客户端,服务端
- 传输完成,释放链接,效率低
UDP:约等于发短信
- 不连接,不稳定
- 客户端,服务端,没有明确的界限
- 不管你有没有准备好都发给你
TCP
客户端
- 连接服务器 Socket
- 发送消息 OutputStream
package com.taodou.tcp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestTcpClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
//服务器地址与端口号
try {
InetAddress server = InetAddress.getByName("127.0.0.1");
int post = 9999;
//创建连接
socket = new Socket(server,post);
//发消息
outputStream = socket.getOutputStream();
outputStream.write("连接成功".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
服务器
- 建立服务的端口 ServerSocket
- 等待客户连接 serverSocket.accept()
- 接收消息 InputStream
package com.taodou.tcp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestTcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
//创建一个地址
serverSocket = new ServerSocket(9999);
//等待客户端连接
socket = serverSocket.accept();
//读取信息
inputStream = socket.getInputStream();
//使用管道
byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len=inputStream.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println(byteArrayOutputStream.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭所有资源
if (byteArrayOutputStream!=null){
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream!=null){
try {
inputStream.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();
}
}
}
}
}
文件上传
服务器
处理错误代码太繁琐不想打,先全部抛出
package com.taodou.tcp;
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 TestTcpServer2 {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
//接收文件
FileOutputStream fos = new FileOutputStream(new File("receive.png"));
byte[] bytes = new byte[1024];
int len;
while ((len=is.read(bytes))!=-1){
fos.write(bytes,0,len);
}
//通知客户端我接收完毕
OutputStream os = socket.getOutputStream();
os.write("接收完成".getBytes());
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
客户端
package com.taodou.tcp;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TestTcpClient2 {
public static void main(String[] args) throws Exception{
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9999);
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fin = new FileInputStream(new File("NET/TCP.png"));
byte[] bytes = new byte[1024];
int len;
while ((len=fin.read(bytes))!=-1){
os.write(bytes,0,len);
}
//传输完毕通知服务器
socket.shutdownOutput();
//等待服务器接收在关闭
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes2 = new byte[1024];
int len2;
while ((len2=is.read(bytes2))!=-1){
baos.write(bytes2,0,len2);
}
System.out.println(baos.toString());
baos.close();
is.close();
fin.close();
os.close();
socket.close();
}
}
UDP
发送端
package com.taodou.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//发送端
public class TestUdpSend {
public static void main(String[] args) throws Exception {
//建立一个Socket
DatagramSocket socket = new DatagramSocket();
//建一个包
String mag = "123124";
InetAddress localHost = InetAddress.getLocalHost();
int post = 9999;
//信息,信息开始位置,信息结束位置,接收地址,接收端口号
DatagramPacket packet = new DatagramPacket(mag.getBytes(),0,mag.length(),localHost,post);
//发送包
socket.send(packet);
socket.close();
}
}
接收端
package com.taodou.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//接收端
public class TestUdpReceive {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9999);
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(packet);//阻塞接收
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
}
}
循环发送消息
发送端
package com.taodou.udp;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//发送端
public class TestUdpSend2 {
public static void main(String[] args) throws Exception {
//建立一个Socket
DatagramSocket socket = new DatagramSocket();
while (true){
//信息从控制台读取
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String mag = reader.readLine();
//信息,信息开始位置,信息结束位置,接收地址,接收端口号
DatagramPacket packet = new DatagramPacket(mag.getBytes(),0,mag.length(),InetAddress.getLocalHost(),9999);
//发送包
socket.send(packet);
if (mag.equals("bye")){
break;
}
}
socket.close();
}
}
接收端
package com.taodou.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//接收端
public class TestUdpReceive2 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9999);
while (true){
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(packet);//阻塞接收
String data = new String(new String(packet.getData(),0,packet.getLength()));
System.out.println(data);
if (data.equals("bye")){
break;
}
}
socket.close();
}
}
多线程实现聊天
老师
package com.taodou.udp;
public class Teacher {
public static void main(String[] args) {
//发送端第一个为自身端口(多余懒得删),发送到,对方端口
new Thread(new TestSend(6666,"LocalHost",7777)).start();
//接收端口号,对方身份
new Thread(new TestReceive(9999,"学生")).start();
}
}
学生
package com.taodou.udp;
public class Student {
public static void main(String[] args) {
new Thread(new TestSend(8888,"LocalHost",9999)).start();
new Thread(new TestReceive(7777,"老师")).start();
}
}
发送端
package com.taodou.udp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//实现接口
public class TestSend implements Runnable{
//定义信息
DatagramSocket socket = null;
BufferedReader reader = null;
int myPost;
String address;
int post;
//构造方法初始化变量
public TestSend(int myPost, String address, int post) {
this.myPost = myPost;
this.address = address;
this.post = post;
try {
socket = new DatagramSocket(myPost);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (true){
String mag = reader.readLine();
//信息,信息开始位置,信息结束位置,接收地址,接收端口号
DatagramPacket packet = new DatagramPacket(mag.getBytes(),0,mag.length(), InetAddress.getByName(address),post);
//发送包
socket.send(packet);
if (mag.equals("bye")){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
socket.close();
}
}
接收端
package com.taodou.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class TestReceive implements Runnable{
DatagramSocket socket = null;
int myPost;
String who;
public TestReceive(int myPost, String who) {
this.myPost = myPost;
this.who = who;
try {
socket = new DatagramSocket(myPost);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (true){
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(packet);//阻塞接收
String data = new String(packet.getData(),0,packet.getLength());
System.out.println(who+":"+data);
if (data.equals("bye")){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
socket.close();
}
}