一 网络编程
1 1.1 概念:也叫socket编程,套接字编程;网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一识别的标识符套接字。
1.2 原理:通信两端都有socket;
网络通信其实就是socket通信;
数据在两个socket间通过IO传输。
1.3 三要素:
(1)ip:一个计算机的标识
127.0.0.1 本地回环地址 用来做一些本地测试
ping IP地址: 用来检测本机是否可以和指定的IP地址的计算机可以进行正常通讯
ipconfig: 用来查看IP地址
xxx.xxx.xxx.255 广播地址
(2)端口号:应用程序都会对应一个端口,用来进行通信。
物理端口 物理设备对应的端口, 网卡口
逻辑端口 用来标示我们的计算机上的进程 , 端口号的有效范围应该是 0-65535 ,
其中0-1024被系统占用或者保留
(3)协议:通信规则,分为UDP和TCP
2 UDP
2.1 特点:
1.把数据打包
2.不需要建立连接,也称为面向无连接协议
3.数据需打包,数据大小有限制64k
4.无需建立连接,所以不可靠
5.速度快
2.2 通信步骤:
1 发送端步骤:
(1)创建UDP发送数据的socket对象;(DatagramSocket)
(2)创建数据包,并给出相关数据参数;(DatagramPacket)
(3)通过socket对象发送数据;(send)
(4)释放资源;(close)
2 接收端步骤:
(1)创建UDP接收数据的socket对象;(DatagramSocket)
(2)创建接收数据包;(DatagramPacket)
(3)接收数据;(receive)
(4)解析数据包;(getData)
(5)释放资源;close
2.3 案例
1 实现数据发送和接收
package udp_01;
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 Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket();
//创建数据包
byte[] buf = "hello".getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 4399;
DatagramPacket dp = new DatagramPacket(buf, len, address, port);
//发送数据
ds.send(dp);
//释放资源
ds.close();
}
}
package udp_01;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpServer {
public static void main(String[] args) throws Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket(4399);
//创建数据包
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);
//接受数据
ds.receive(dp);
//解析数据
byte[] data = dp.getData();
int l = dp.getLength();
System.out.println(new String(data,0,l));
//释放资源
ds.close();
}
}
2 键盘录入数据实现数据的动态发送
package udp_02;
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 {
//需求:键盘录入数据实现数据的动态发送
//创建socket对象
DatagramSocket ds = new DatagramSocket();
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
String line;
while((line = sc.nextLine())!=null){
//创建数据包
byte[] buf = line.getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 4400;
DatagramPacket dp = new DatagramPacket(buf,len,address,port );
//发送数据
ds.send(dp);
}
//释放资源
ds.close();
}
}
package udp_02;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpServer {
public static void main(String[] args) throws Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket(4400);
while(true){
//创建数据包
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);
//接受数据
ds.receive(dp);
//解析数据
byte[] data = dp.getData();
int l = dp.getLength();
System.out.println(new String(data,0,l));
}
}
}
3 多线程实现聊天室(相当于是将发送数据端和接收数据端合并)
package Udp_03;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
public class UdpClient implements Runnable{
DatagramSocket ds ;
public UdpClient(DatagramSocket ds){
this.ds = ds;
}
public void run() {
try {
DatagramSocket ds = new DatagramSocket();
Scanner sc = new Scanner(System.in);
String line;
while((line=sc.nextLine())!=null){
byte[] buf = line.getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 5000;
DatagramPacket dp = new DatagramPacket(buf, len, address, port);
ds.send(dp);
}
ds.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package Udp_03;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpServer implements Runnable{
DatagramSocket ds;
public UdpServer(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run() {
try {
DatagramSocket ds = new DatagramSocket();
while(true){
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);
ds.receive(dp);
byte[] data = dp.getData();
int length = dp.getLength();
System.out.println(new String(data,0,length));
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package Udp_03;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatRoom {
public static void main(String[] args) throws Exception {
new Thread(new UdpClient(new DatagramSocket())).start();
new Thread(new UdpServer(new DatagramSocket(5000))).start();
}
}
3 TCP
3.1 特点:
1.需要建立通道
2.无限制传送大量数据
3.面向连接
4.可靠
5.速度慢
3.2 通信步骤:
1 发送端步骤:
(1)创建TCP发送端的socket对象;(Socket)
(2)获取输出流,并写数据(getOutputStream,write)
(3)释放资源;(close)
2 接收端步骤:
(1)创建TCP接收端的socket对象;(ServerSocket)
(2)监听客户端的链接;(accept)
(3)获取输入流并读取数据;(inputStream,read)
(4)输出;
(5)释放资源;(close)
3.3 案例
1 用TCP协议写一个数据的发送和接收,接收端接收到数据之后给发送端一个反馈
package tcp_02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClient {
public static void main(String[] args) throws IOException, Exception {
Socket sk = new Socket("127.0.0.1",9876);
OutputStream os = sk.getOutputStream();
os.write("你喜欢的是谁?".getBytes());
InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
sk.close();
}
}
package tcp_02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(9876);
Socket sk = ss.accept();
InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
OutputStream os = sk.getOutputStream();
os.write("刘诗诗".getBytes());
sk.close();
}
}
2 需求: 客户端键盘录入数据,服务器端接收数据在控制台输出
package tcp_03;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10086);
Socket sk = ss.accept();
while(true){
InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
}
}
}
package tcp_03;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class TcpClient {
public static void main(String[] args) throws Exception, IOException {
Socket sk = new Socket("127.0.0.1",10086);
Scanner sc = new Scanner(System.in);
String line;
while((line=sc.nextLine())!=null){
OutputStream os = sk.getOutputStream();
os.write(line.getBytes());
}
sk.close();
}
}
3 运用多线程实现文本文件的上传
分析:客户端:(1)读取文本文件中的数据
(2)通过管道流将读取的数据发送到管道中(服务器端)
服务器:(1)从管道流中读取数据
(2)把读取的文件写入到文本文件中
package tcp_06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClient {
public static void main(String[] args) throws Exception, IOException {
Socket sk = new Socket("127.0.0.1",7878);
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
sk.close();
}
}
package tcp_06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerThread implements Runnable{
Socket sk;
public ServerThread(Socket sk){
this.sk = sk;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
BufferedWriter bw = new BufferedWriter(new FileWriter(new UUIDUtils().getFilename()));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package tcp_06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(7878);
while(true){
Socket sk = ss.accept();
new Thread(new ServerThread(sk)).start();
}
}
}
package tcp_06;
import java.util.UUID;
public class UUIDUtils {
public static String getFilename(){
String filename = UUID.randomUUID().toString();
return filename;
}
}
4 至此java中的网络编程部分结束,你只需要明确最重要一点:发送端就是客户端就是将数据发送到管道流中;接收端就是服务器端则是取出管道中的数据进行处理。
注意:java.net.ConnectException: Connection refused: connect
TCP协议是不能直接运行客户端的,必须先运行服务器。因为他是一种可靠的协议。
1 1.1 概念:也叫socket编程,套接字编程;网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一识别的标识符套接字。
1.2 原理:通信两端都有socket;
网络通信其实就是socket通信;
数据在两个socket间通过IO传输。
1.3 三要素:
(1)ip:一个计算机的标识
127.0.0.1 本地回环地址 用来做一些本地测试
ping IP地址: 用来检测本机是否可以和指定的IP地址的计算机可以进行正常通讯
ipconfig: 用来查看IP地址
xxx.xxx.xxx.255 广播地址
(2)端口号:应用程序都会对应一个端口,用来进行通信。
物理端口 物理设备对应的端口, 网卡口
逻辑端口 用来标示我们的计算机上的进程 , 端口号的有效范围应该是 0-65535 ,
其中0-1024被系统占用或者保留
(3)协议:通信规则,分为UDP和TCP
2 UDP
2.1 特点:
1.把数据打包
2.不需要建立连接,也称为面向无连接协议
3.数据需打包,数据大小有限制64k
4.无需建立连接,所以不可靠
5.速度快
2.2 通信步骤:
1 发送端步骤:
(1)创建UDP发送数据的socket对象;(DatagramSocket)
(2)创建数据包,并给出相关数据参数;(DatagramPacket)
(3)通过socket对象发送数据;(send)
(4)释放资源;(close)
2 接收端步骤:
(1)创建UDP接收数据的socket对象;(DatagramSocket)
(2)创建接收数据包;(DatagramPacket)
(3)接收数据;(receive)
(4)解析数据包;(getData)
(5)释放资源;close
2.3 案例
1 实现数据发送和接收
package udp_01;
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 Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket();
//创建数据包
byte[] buf = "hello".getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 4399;
DatagramPacket dp = new DatagramPacket(buf, len, address, port);
//发送数据
ds.send(dp);
//释放资源
ds.close();
}
}
package udp_01;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpServer {
public static void main(String[] args) throws Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket(4399);
//创建数据包
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);
//接受数据
ds.receive(dp);
//解析数据
byte[] data = dp.getData();
int l = dp.getLength();
System.out.println(new String(data,0,l));
//释放资源
ds.close();
}
}
2 键盘录入数据实现数据的动态发送
package udp_02;
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 {
//需求:键盘录入数据实现数据的动态发送
//创建socket对象
DatagramSocket ds = new DatagramSocket();
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
String line;
while((line = sc.nextLine())!=null){
//创建数据包
byte[] buf = line.getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 4400;
DatagramPacket dp = new DatagramPacket(buf,len,address,port );
//发送数据
ds.send(dp);
}
//释放资源
ds.close();
}
}
package udp_02;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpServer {
public static void main(String[] args) throws Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket(4400);
while(true){
//创建数据包
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);
//接受数据
ds.receive(dp);
//解析数据
byte[] data = dp.getData();
int l = dp.getLength();
System.out.println(new String(data,0,l));
}
}
}
3 多线程实现聊天室(相当于是将发送数据端和接收数据端合并)
package Udp_03;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
public class UdpClient implements Runnable{
DatagramSocket ds ;
public UdpClient(DatagramSocket ds){
this.ds = ds;
}
public void run() {
try {
DatagramSocket ds = new DatagramSocket();
Scanner sc = new Scanner(System.in);
String line;
while((line=sc.nextLine())!=null){
byte[] buf = line.getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 5000;
DatagramPacket dp = new DatagramPacket(buf, len, address, port);
ds.send(dp);
}
ds.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package Udp_03;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpServer implements Runnable{
DatagramSocket ds;
public UdpServer(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run() {
try {
DatagramSocket ds = new DatagramSocket();
while(true){
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);
ds.receive(dp);
byte[] data = dp.getData();
int length = dp.getLength();
System.out.println(new String(data,0,length));
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package Udp_03;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatRoom {
public static void main(String[] args) throws Exception {
new Thread(new UdpClient(new DatagramSocket())).start();
new Thread(new UdpServer(new DatagramSocket(5000))).start();
}
}
3 TCP
3.1 特点:
1.需要建立通道
2.无限制传送大量数据
3.面向连接
4.可靠
5.速度慢
3.2 通信步骤:
1 发送端步骤:
(1)创建TCP发送端的socket对象;(Socket)
(2)获取输出流,并写数据(getOutputStream,write)
(3)释放资源;(close)
2 接收端步骤:
(1)创建TCP接收端的socket对象;(ServerSocket)
(2)监听客户端的链接;(accept)
(3)获取输入流并读取数据;(inputStream,read)
(4)输出;
(5)释放资源;(close)
3.3 案例
1 用TCP协议写一个数据的发送和接收,接收端接收到数据之后给发送端一个反馈
package tcp_02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClient {
public static void main(String[] args) throws IOException, Exception {
Socket sk = new Socket("127.0.0.1",9876);
OutputStream os = sk.getOutputStream();
os.write("你喜欢的是谁?".getBytes());
InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
sk.close();
}
}
package tcp_02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(9876);
Socket sk = ss.accept();
InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
OutputStream os = sk.getOutputStream();
os.write("刘诗诗".getBytes());
sk.close();
}
}
2 需求: 客户端键盘录入数据,服务器端接收数据在控制台输出
package tcp_03;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10086);
Socket sk = ss.accept();
while(true){
InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
}
}
}
package tcp_03;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class TcpClient {
public static void main(String[] args) throws Exception, IOException {
Socket sk = new Socket("127.0.0.1",10086);
Scanner sc = new Scanner(System.in);
String line;
while((line=sc.nextLine())!=null){
OutputStream os = sk.getOutputStream();
os.write(line.getBytes());
}
sk.close();
}
}
3 运用多线程实现文本文件的上传
分析:客户端:(1)读取文本文件中的数据
(2)通过管道流将读取的数据发送到管道中(服务器端)
服务器:(1)从管道流中读取数据
(2)把读取的文件写入到文本文件中
package tcp_06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClient {
public static void main(String[] args) throws Exception, IOException {
Socket sk = new Socket("127.0.0.1",7878);
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
sk.close();
}
}
package tcp_06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerThread implements Runnable{
Socket sk;
public ServerThread(Socket sk){
this.sk = sk;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
BufferedWriter bw = new BufferedWriter(new FileWriter(new UUIDUtils().getFilename()));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package tcp_06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(7878);
while(true){
Socket sk = ss.accept();
new Thread(new ServerThread(sk)).start();
}
}
}
package tcp_06;
import java.util.UUID;
public class UUIDUtils {
public static String getFilename(){
String filename = UUID.randomUUID().toString();
return filename;
}
}
4 至此java中的网络编程部分结束,你只需要明确最重要一点:发送端就是客户端就是将数据发送到管道流中;接收端就是服务器端则是取出管道中的数据进行处理。
注意:java.net.ConnectException: Connection refused: connect
TCP协议是不能直接运行客户端的,必须先运行服务器。因为他是一种可靠的协议。