Java之网络编程基础
推荐资源站:https://zhimalier.com/
前天对java网络基础进行了以下总结,相信会有很多不足之处!请大牛多多指导,以寻求更好的进步! 在此之前,先说一说基础知识,个人对概念性的知识不是太感冒,但是不了解的话会很坑的。所以喽,还是总结看看!
一、网络的基本概念
1、计算机网络,说白了就是把分布在不同地区的计算机通过线等设备链接起来,形成一个大规模的网络系统,从而达到信息的传递。
2、网络体系:国际化标准组织ISO在1978年提出了OSI(Open System Interconnection)模型,中文名是开放系统互联参考模式,它把网络分为了7层物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
网络编程额三要素:IP地址、端口号、通信协议
IP地址(IP Address)
每台主机都必须有一个唯一的,因特网的IP地址具有全球唯一性!
IP地址IP地址 = 网络ID +主机ID
网络ID:标识计算机或网络设备所在的网段
主机ID:标识特定主机或网络设备
格式:int型、 32位、由4个8位二进制数组成
端口号
Ip地址其实就是方便找到你想联系的电脑,而端口号则标明的是该计算机的程序应用。他是抽象的软件结构。端口号可以从0到65535,通常分为3类:
*、公认端口(Well Known Ports):从0到1023,它们紧密绑定(Binding)一些服务。
*、注册端口(Registered Ports):从1024到49151。它们松散地绑定一些服务。
*、动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535,这些端口是应用程序使用的动态端口,应用程序一般不会主动使用这些端口。
两类传输通信协议
1、TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个 socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。
2、UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
TCP/IP虽然名字是TCP,但是他的传输层包含TCP和UDP两个协议
比较: UDP相当于发短信(有字数限制)
不需要建立链接
数据报的大小限制在64K内
效率高,不安全,容易丢包
TCP相当于打电话,需要建立链接
效率相对较低,数据传输安全
三次握手 (点名-->签到-->确认)
二、socket套接字的java网络编程
1、TCP对应的是服务器的ServerSocket和客户端的SocketJava中使用Socket完成TCP程序的开发,使用此类可以方便的建立可靠的、双向的、持续性的、点对点的通讯连接
在Socket的程序开发中,服务器端使用ServerSocket等待客户端的连接,对于java的网络程序来讲,每一个客户端都使用一个Socket对象表示。
socket通讯流程:
(1)创建Socket(客户端) ServerSocket(服务端)
(2)客户端/服务端打开并连接Socket的输入/输出流
(3)按照一定的规则进行读/写操作
(4)关闭Socket相关
-
//实例代码
-
import java.io.BufferedReader;
-
import java.io.BufferedWriter;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.OutputStream;
-
import java.io.OutputStreamWriter;
-
import java.net.Socket;
-
import java.net.UnknownHostException;
-
/**
-
* TCP socket网络编程
-
* 1、服务器serversocket建立一个服务器端,还有一个客户端,两者通过
-
socket对象建立通道连接起来
-
* 2、两者可以通过流进行数据传输 如果数据有类型,使用
-
datainputStream dataoutputStream, object
-
* 3、实际上数据访问还是通过流实现的,但是两端都是来自网络
-
* @author Administrator
-
*
-
*/
-
public class LoginClient {
-
//使用字符流发送数据,一定要及时刷新flush,每写一行数据需要 newline
-
public static void main(String[] args) throws UnknownHostException, IOException {
-
//1、socket套接字,用来打通通道
-
Socket s = new Socket("127.0.0.1",8888);//打开了本机上的端口号为8888的程序的通道
-
//输出流,用来向服务器发送数据
-
OutputStream os = s.getOutputStream();
-
InputStream is = s.getInputStream();
-
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
-
bw.write("发送第一行内容");
-
bw.newLine();
-
bw.write("发送第二行内容");
-
bw.newLine();
-
bw.flush();
-
//2、拿到服务器给出的反馈
-
BufferedReader br = new BufferedReader(new InputStreamReader(is));
-
System.out.println(br.readLine());
-
//3、关闭流
-
br.close();
-
bw.close();
-
is.close();
-
os.close();
-
s.close();
-
}
-
-
}
-
-
import java.io.BufferedReader;
-
import java.io.BufferedWriter;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.OutputStream;
-
import java.io.OutputStreamWriter;
-
import java.net.ServerSocket;
-
import java.net.Socket;
-
-
/**
-
* Tcp Socket 双向: 客户端向服务器发送数据,服务器接收到之后给出反馈 模拟登陆
-
* @author Administrator
-
*
-
*/
-
public class LoginServer {
-
public static void main(String[] args) throws IOException {
-
// 1、创建serversocket对象,并指定地址和端口号
-
ServerSocket ss = new ServerSocket(8888);
-
// 2、使用serversocket拿到 socket对象,socket是一个套接字,连接应用层和传输层,打开通道
-
Socket s = ss.accept();
-
// 3、socket对象拿到了访问该服务器的对象的数据
-
InputStream is = s.getInputStream();
-
OutputStream os = s.getOutputStream();
-
// 处理拿到的数据
-
BufferedReader br = new BufferedReader(new InputStreamReader(is));
-
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
-
String name = br.readLine();
-
String pwd = br.readLine();
-
System.out.println(name+"\t"+pwd+"登陆服务器");
-
if (name.equals("bjsxt") && pwd.equals("bjsxt")) {
-
// 当登陆成功,给用户反馈成功
-
bw.write("恭喜你登陆成功!!!!");
-
bw.flush();
-
} else {
-
bw.write("账号或密码错误!!!!");
-
bw.flush();
-
}
-
//4、关闭流
-
bw.close();
-
br.close();
-
os.close();
-
is.close();
-
s.close();
-
ss.close();
-
}
-
}
-
-
//对象流的代码实例
-
-
import java.io.Serializable;
-
-
/**
-
* 封装了用户信息
-
* @author Administrator
-
*
-
*/
-
public class User implements Serializable{
-
String name;//登录账号
-
String pwd;//密码
-
int id;//身份标识
-
public User(String name, String pwd, int id) {
-
super();
-
this.name = name;
-
this.pwd = pwd;
-
this.id = id;
-
}
-
-
}
-
-
import java.io.BufferedReader;
-
import java.io.BufferedWriter;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.ObjectInputStream;
-
import java.io.ObjectOutputStream;
-
import java.io.OutputStream;
-
import java.io.OutputStreamWriter;
-
import java.net.Socket;
-
import java.net.UnknownHostException;
-
-
/**
-
* 基于TCP协议的 socket网络编程 1、服务器serversocket建立一个服务器端,还有一个客户
-
-
端,两者通过socket对象建立通道连接起来
-
* 2、两者可以通过流进行数据传输 如果数据有类型,使用datainputStream
-
dataoutputStream, object
-
* 3、实际上数据访问还是通过流实现的,但是两端都是来自网络
-
* @author Administrator
-
*
-
*/
-
public class LoginClient {
-
// 使用字符流发送数据,一定要及时刷新flush,每写一行数据需要 newline
-
public static void main(String[] args) throws UnknownHostException,
-
IOException {
-
Socket s = new Socket("127.0.0.1", 8888);
-
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
-
oos.writeObject(new User("望舒", "111111", 1));
-
// 读取服务器给的反馈
-
InputStream is = s.getInputStream();
-
BufferedReader br = new BufferedReader(new InputStreamReader(is));
-
System.out.println(br.readLine());
-
// 关闭流
-
is.close();
-
oos.close();
-
s.close();
-
}
-
}
-
-
import java.io.BufferedOutputStream;
-
import java.io.BufferedReader;
-
import java.io.BufferedWriter;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.ObjectInputStream;
-
import java.io.OutputStream;
-
import java.io.OutputStreamWriter;
-
import java.net.ServerSocket;
-
import java.net.Socket;
-
-
/**
-
* Tcp Socket 双向: 客户端向服务器发送对象,服务器接收到之后给出反馈 模拟登陆
-
* 利用线程知识 可以多客户端
-
* @author Administrator
-
*
-
*/
-
public class LoginServer {
-
-
public static void main(String[] args) throws IOException,
-
ClassNotFoundException {
-
// 1、创建一个服务器,指定端口号
-
ServerSocket ss = new ServerSocket(8888);
-
boolean flag = true;
-
while (flag) {
-
Socket s = ss.accept();
-
new LoginThread(s).start();
-
}
-
ss.close();
-
}
-
}
-
-
class LoginThread extends Thread {
-
Socket s = null;
-
-
public LoginThread(Socket s) {
-
this.s = s;
-
}
-
-
@Override
-
public void run() {
-
try {
-
login();
-
} catch (ClassNotFoundException | IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
}
-
-
// 接收客户端信息的方法
-
public void login() throws IOException, ClassNotFoundException {
-
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
-
User user = (User) ois.readObject(); //向下转型
-
System.out.println(user.name + "正在登录");
-
OutputStream os = s.getOutputStream();
-
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
-
bw.write("服务端接收成功");
-
bw.flush();
-
os.close();
-
ois.close();
-
s.close();
-
}
-
}
2、UDP对应的是DatagramSocket。
实现流程:
服务器端(server):
1. 构造DatagramSocket实例,指定本地端口。
2. 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。
3. 通过DatagramSocket的send和receive方法来收和发DatagramPacket.
客户端(client):
1. 构造DatagramSocket实例。
2.通过DatagramSocket实例的send和receive方法发送DatagramPacket报文。
3.结束后,调用DatagramSocket的close方法关闭。
不多说,实例代码:
-
import java.net.DatagramPacket;
-
import java.net.DatagramSocket;
-
import java.net.InetAddress;
-
import java.net.SocketException;
-
import java.util.Scanner;
-
-
/**
-
* 一对多聊天
-
*
-
* @author Administrator
-
*
-
*/
-
public class UdpServer {
-
-
public static void main(String[] args) throws Exception {
-
// 服务器
-
DatagramSocket ds = new DatagramSocket(6666);
-
Scanner input = new Scanner(System.in);
-
boolean flag = true;
-
while (flag) {
-
// dengdai客户端发送消息
-
byte bs[] = new byte[1024];
-
DatagramPacket dp = new DatagramPacket(bs, bs.length);
-
ds.receive(dp);
-
// 解析数据
-
String str = new String(dp.getData(), 0, dp.getLength());
-
// str xiaomi:string
-
System.out.println(str);
-
// 端口号和ip地址不确定
-
int port = dp.getPort();
-
InetAddress ia = dp.getAddress();
-
System.out.println(ia.getHostAddress());
-
String msg = input.next();
-
// 把消息发送给客户端
-
DatagramPacket dp1 = new DatagramPacket(msg.getBytes(),
-
msg.getBytes().length, ia, port);
-
ds.send(dp1);
-
}
-
ds.close();
-
}
-
}
-
-
import java.net.DatagramPacket;
-
import java.net.DatagramSocket;
-
import java.net.InetAddress;
-
import java.net.SocketException;
-
import java.util.Scanner;
-
-
public class UdpClient {
-
-
public static void main(String[] args) throws Exception {
-
// 1、创建一个客户端 并指定端口
-
DatagramSocket ds = new DatagramSocket(8881);
-
boolean flag = true;
-
while (flag) {
-
// 2、准备数据
-
Scanner input = new Scanner(System.in);
-
String str = input.next();
-
str = "客户端说:"+str;
-
//结束客户端
-
if(str.equals("exit") || str.equals("quit")){
-
break; //打断循环
-
//continue: 打断当前这次循环执行下一次
-
//return 结束方法
-
}
-
// 3、打包数据
-
DatagramPacket dp = new DatagramPacket(str.getBytes(),
-
str.getBytes().length,
-
InetAddress.getByName("192.168.1.218"), 8888);
-
// 4、发送数据
-
ds.send(dp);
-
// 5、接收服务器端的反馈
-
byte[] buf = new byte[1024];
-
DatagramPacket dp1 = new DatagramPacket(buf, buf.length);
-
ds.receive(dp1);
-
System.out.println("服务器说:" + new String(dp1.getData()));
-
// 6、关闭客户端
-
}
-
ds.close();
-
}
-
}
-
-
//实例二:发送文件
-
import java.io.BufferedOutputStream;
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
import java.net.DatagramPacket;
-
import java.net.DatagramSocket;
-
import java.net.SocketException;
-
-
/**
-
* 通过udp传递文件
-
* @author Administrator
-
*
-
*/
-
public class UdpServer {
-
-
public static void main(String[] args) {
-
DatagramSocket ds = null;
-
boolean flag = true;
-
try {
-
BufferedOutputStream bos = new BufferedOutputStream(
-
new FileOutputStream("e:\\xiaomiyanzhao.gif", true));
-
ds = new DatagramSocket(6666);
-
// 等待接收数据
-
byte[] bs = new byte[2000];
-
while (flag) {
-
DatagramPacket dp = new DatagramPacket(bs, 0, bs.length);
-
// 把数据读取到数据报中
-
ds.receive(dp);
-
// 输出流输出数据
-
bos.write(dp.getData(),0,dp.getLength());
-
}
-
bos.close();
-
} catch (SocketException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
} catch (IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
} finally {
-
ds.close();
-
}
-
}
-
}
-
-
import java.io.BufferedInputStream;
-
import java.io.FileInputStream;
-
import java.io.IOException;
-
import java.net.DatagramPacket;
-
import java.net.DatagramSocket;
-
import java.net.InetAddress;
-
import java.net.SocketException;
-
-
public class UdpClient {
-
// 客户端,用来发送文件
-
public static void main(String[] args) throws IOException {
-
DatagramSocket ds = new DatagramSocket(8888);
-
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
-
"d:\\5.gif"));
-
byte bs[] = new byte[1024];
-
int len;
-
while ((len = bis.read(bs)) != -1) {
-
DatagramPacket dp = new DatagramPacket(bs, len,
-
InetAddress.getByName("192.168.1.218"), 6666);
-
ds.send(dp);
-
}
-
System.out.println("发送成功-----》");
-
bis.close();
-
ds.close();
-
}
-
}
说了这么多 还是自己敲代码来的实在!! 先到这不写了,敲代码去!!
文章来源: zhima.blog.csdn.net,作者:芝麻粒儿,版权归原作者所有,如需转载,请联系作者。
原文链接:zhima.blog.csdn.net/article/details/52073792
- 点赞
- 收藏
- 关注作者
评论(0)