网络编程网络编程3要素
IP获取
UDP传输协议(多线程传输)
TCP传输协议(多线程)
网络编程3要素
网络编程(三要素)
1、 IP地址:一栋小区楼相当于IP地址
2、 端口号:小区内每一个住户相当于端口号
3、 协议:每个住户间来往原则
网络编程(二协议)
UDP:面向无连接,数据不安全,速度快,不区分客户端和服务器端。
TCP:面向连接(三次连接),数据安全,速度略低,分为客户端和服务端。
三次握手:客户端先向服务端发起请求,服务器响应请求,传输数据。
Socket通信原理
1、 套接字是两台机器之间通讯的端点
2、网络通信其实就是Socket之间的通信
3、数据在两个Socket之间通过IO流传输
一、IP
package exercise;
import java.net.InetAddress;
public class exercise {
public static void main(String[] args) throws Exception {
InetAddress host=InetAddress.getLocalHost();//创建对象
String ip=host.getHostAddress();//获取本机IP地址
System.out.println(ip);
}
}
上面获取IP是172.16.56.21,然后打开控制台,ping 172.16.56.21,如果成功就代表正确。
二、Socket
/*
作用:进行不同的程序之间的通信
原理:
1. 服务端开启8888端口,并监听着,时刻等待着客户端的连接请求
2. 客户端知道服务端的ip地址和监听端口号,发出请求到服务端
客户端的端口地址是系统分配的,通常都会大于1024
一旦建立了连接,服务端会得到一个新的Socket对象,该对象负责与客户端进行通信。
*/
模拟练习
package com.llhc;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {//服务端
public static void main(String[] args) throws IOException{
try{
ServerSocket ss = new ServerSocket(8888);//打开端口
Socket s=ss.accept();//开启监听
InputStream is=s.getInputStream();//用流
int count=is.read();
System.out.println(count);
ss.close();
s.close();
is.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
package com.llhc;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
//客户端
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("127.0.0.1",8888);//链接本地端口
OutputStream os=s.getOutputStream();//读写文件
os.write(110);
os.close();
s.close();
}
}
三、UDP传输协议(多线程传输):QQ、微信、视频聊天。
package exercise;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class exercise {
/**
* @param args
*/
public static void main(String[] args) {
new Receive().start();
new Send().start();
}
}
//接收端
class Receive extends Thread {
public void run() {
try {
DatagramSocket socket = new DatagramSocket(9999); //创建Socket相当于创建码头
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet相当于创建集装箱
while(true) {
socket.receive(packet); //接货,接收数据
byte[] arr = packet.getData(); //获取数据
int len = packet.getLength(); //获取有效的字节个数
String ip = packet.getAddress().getHostAddress(); //获取ip地址
int port = packet.getPort(); //获取端口号
System.out.println("接收数据是:"+ip + ":" + port + ":" + new String(arr,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//发送端
class Send extends Thread {
public void run() {
try {
Scanner sc = new Scanner(System.in); //创建键盘录入对象
DatagramSocket socket = new DatagramSocket(); //创建Socket相当于创建码头
while(true) {
String line = sc.nextLine(); //获取键盘录入的字符串
if("quit".equals(line)) {
break;
}
DatagramPacket packet = //创建Packet相当于集装箱
new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("127.0.0.1"), 9999);
socket.send(packet); //发货,将数据发出去
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、TCP传输协议(多线程):文件传输、邮件。
Client发送端:
package exercise;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
/**
* * 1.客户端
* 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
* 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
* 输入流可以读取服务端输出流写出的数据
* 输出流可以写出数据到服务端的输入流
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 12345);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //将字节流包装成了字符流
PrintStream ps = new PrintStream(socket.getOutputStream()); //PrintStream中有写出换行的方法
System.out.println(br.readLine());
ps.println("我想报名黑马程序员");
System.out.println(br.readLine());
ps.println("大哭!!!能不能给次机会");
socket.close();
}
}
Server服务端:
package exercise;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
/**
* * 2.服务端
* 创建ServerSocket(需要指定端口号)
* 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
* 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
* 输入流可以读取客户端输出流写出的数据
* 输出流可以写出数据到客户端的输入流
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//demo1();
ServerSocket server = new ServerSocket(12345);
while(true) {
final Socket socket = server.accept(); //接受客户端的请求
new Thread() {
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //将字节流包装成了字符流
PrintStream ps = new PrintStream(socket.getOutputStream()); //PrintStream中有写出换行的方法
ps.println("欢迎咨询黑马程序员");
System.out.println(br.readLine());
ps.println("不好意思,爆满了");
System.out.println(br.readLine());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
public static void demo1() throws IOException {
ServerSocket server = new ServerSocket(12345);
Socket socket = server.accept(); //接受客户端的请求
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //将字节流包装成了字符流
PrintStream ps = new PrintStream(socket.getOutputStream()); //PrintStream中有写出换行的方法
ps.println("欢迎咨询黑马程序员");
System.out.println(br.readLine());
ps.println("不好意思,爆满了");
System.out.println(br.readLine());
socket.close();
}
}