网络编程基本概念
- TCP: 传输控制协议,采用三方握手的方式,保证准确的连接操作
- UDP: 数据报协议,发送数据报【不安全、不可靠】
- 数据帧: 协议类型、源IP、目标IP、源端口、目标端口、帧序号、帧数据
网络编程TCP协议
- TCP是一个可靠的协议,面向连接的协议
- 实现TCP协议,需要编写服务器端和客户端,Java API为我们提供了java.net包,为实现网络应用程序提供类
- ServerSocket 此类实现服务器套接字
- Socket 此类实现客户端套接字 【是网络驱动层提供给应用程序编程的接口和一种机制】
数据发送过程【IO流】
实现服务器端与客户端程序
public class ServerSocket extends Object
ServerSocket(int port)
void setTimeout(int timeout)
InetAddress getInetAddress()
Socket accept()
public class Socket extends Object
Socket(String host,int port)
InputStream getInputStream()
OutputStream getOutputStream()
void setSoTimeout(int timeout)
TCP实现ECHO程序
- Echo,应答。
- 客户端向服务器发送一个字符串,服务器不做任何处理,直接把字符串返回给客户端,Echo程序是最为基本的客户/服务器程序
public class EchoServerDemo {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(6666);
System.out.println("服务器已启动,正在等待客户端的连接。。。");
Socket socket = server.accept();
System.out.println("客户端连接成功"+server.getInetAddress().getHostAddress());
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = br.readLine();
System.out.println(info);
PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
ps.println("echo:"+info);
ps.flush();
ps.close();
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public class EchoClientDemo {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost",6666);
PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
ps.println("hello,my name is Bin");
ps.flush();
String info = br.readLine();
System.out.println(info);
ps.close();
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
服务器与多客户端通信
public class MutilServerDemo {
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(3);
try {
ServerSocket server = new ServerSocket(7777);
System.out.println("服务器已启动,等待连接。。。");
while (true){
Socket s = server.accept();
System.out.println(s.getInetAddress().getHostAddress());
es.execute(new UserThread(s));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
class UserThread implements Runnable {
private Socket s;
public UserThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintStream ps = new PrintStream(new BufferedOutputStream(s.getOutputStream()));
String info = br.readLine();
System.out.println(info);
ps.println("echo:"+info);
ps.flush();
ps.close();
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public class MutilClientDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try {
Socket socket = new Socket("localhost",7777);
PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("请输入:");
String info = input.nextLine();
ps.println(info);
ps.flush();
info = br.readLine();
System.out.println(info);
ps.close();
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
多客户端之间的通信
public class Message implements Serializable {
private String from;
private String to;
private int type;
private String info;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public Message(String from, String to, int type, String info) {
this.from = from;
this.to = to;
this.type = type;
this.info = info;
}
public Message() {
}
@Override
public String toString() {
return "Message{" +
"from='" + from + '\'' +
", to='" + to + '\'' +
", type=" + type +
", info='" + info + '\'' +
'}';
}
}
public final class MessageType {
public static final int TYPE_LOGIN = 0x1;
public static final int TYPE_SEND = 0x2;
}
public class Server {
public static void main(String[] args) {
Vector<UserThread> vector = new Vector<>();
ExecutorService es = Executors.newFixedThreadPool(5);
try {
ServerSocket server = new ServerSocket(9999);
System.out.println("服务器已启动。正在等待连接....");
while (true){
Socket socket = server.accept();
UserThread user = new UserThread(socket,vector);
es.execute(user);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
class UserThread implements Runnable{
private String name;
private Socket socket;
private Vector<UserThread> vector;
private ObjectInputStream ois;
private ObjectOutputStream oos;
private boolean flag = true;
public UserThread(Socket socket,Vector<UserThread> vector){
this.socket = socket;
this.vector = vector;
vector.add(this);
}
@Override
public void run() {
try {
System.out.println("客户端"+socket.getInetAddress().getHostAddress()+"已连接");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
while(flag){
Message msg = (Message) ois.readObject();
int type = msg.getType();
switch (type){
case MessageType.TYPE_LOGIN:
name = msg.getFrom();
msg.setInfo("欢迎你:");
oos.writeObject(msg);
break;
case MessageType.TYPE_SEND:
String to = msg.getTo();
UserThread ut;
int size = vector.size();
for (int i = 0; i < size; i++) {
ut = vector.get(i);
if(to.equals(ut.name) && ut != this){
ut.oos.writeObject(msg);
break;
}
}
break;
}
}
ois.close();
oos.close();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
public class Client {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ExecutorService es = Executors.newSingleThreadExecutor();
try {
Socket socket = new Socket("localhost",9999);
System.out.println("服务器连接成功");
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
System.out.println("请输入名称:");
String name = input.nextLine();
Message msg = new Message(name,null,MessageType.TYPE_LOGIN,null);
oos.writeObject(msg);
msg = (Message) ois.readObject();
System.out.println(msg.getInfo()+msg.getFrom());
es.execute(new ReadInfoThread(ois));
boolean flag = true;
while(flag){
msg = new Message();
System.out.println("TO:");
msg.setTo(input.nextLine());
msg.setFrom(name);
msg.setType(MessageType.TYPE_SEND);
System.out.println("Info:");
msg.setInfo(input.nextLine());
oos.writeObject(msg);
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
class ReadInfoThread implements Runnable{
private ObjectInputStream in;
private boolean flag = true;
public void setFlag(boolean flag){
this.flag = flag;
}
public ReadInfoThread(ObjectInputStream in) {
this.in = in;
}
@Override
public void run() {
try{
while(flag){
Message message = (Message) in.readObject();
System.out.println("["+message.getFrom()+"]对我说:"+message.getInfo());
}
if(in != null){
in.close();
}
}catch(IOException|ClassNotFoundException e){
e.printStackTrace();
}
}
}
网络编程UDP协议
- 无连接协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络中以任何可能的路径传往目的地,能否到达目的地、到达目的地的时间以及内容的正确性不能被保证,每个传输的数据报必须限定在64KB之内
DatagramPacket
DatagramSocket
public class UDPClientDemo {
public static void main(String[] args) {
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
try {
DatagramSocket socket = new DatagramSocket(8020);
System.out.println("正在接收数据...");
socket.receive(dp);
String s = new String(dp.getData(),0,dp.getLength());
System.out.println(s);
socket.close();
} catch (SocketException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public class UDPServerDemo {
public static void main(String[] args) {
String info = "good good 学习,天天 up";
byte[] bytes = info.getBytes();
try {
DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length,
InetAddress.getByName("127.0.0.1"),8020);
DatagramSocket socket = new DatagramSocket(9022);
socket.send(dp);
socket.close();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (SocketException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
URL
public class URLDemo {
public static void main(String[] args) {
try {
URL url = new URL("https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("E:\\baidu.png"));
byte[] bytes = new byte[1024];
int len = -1;
while((len=in.read(bytes)) != -1){
out.write(bytes,0,len);
out.flush();
}
in.close();
out.close();
System.out.println("下载成功");
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}