网络编程三要素:端口,协议,IP地址
协议分为UDP协议和TCP协议
一,UDP协议:
UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念
1.UDP发送数据
步骤:
1:创建发送端的socket对象(DatagramSocket)
2:创建数据,并把教据打包
3:调用DatagramSocket对象的方法发送数据
4:关闭发送端
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建发送端的socket对象(DatagramSocket)
//DatagramSocket () 构造数据报套接字并将其绑到本地主机上的任何可用端口
DatagramSocket ds = new DatagramSocket();
//创建数据,并把教据打包
//DatagramPacket (byte[] buf, int length,InetAddress address, int port)
// 构造一个数据包,发送长度为length的数据包到指定主机上的指定端口号。
byte[] bys = "hello,java,word".getBytes();
DatagramPacket dp = new DatagramPacket
(bys,bys.length,InetAddress.getByName("10.67.112.222"),10086);
//调用DatagramSocket对象的方法发送数据
//void send(DatagramSocket p)从此套接字发送数据包
ds.send(dp);
//关闭发送端
ds.close();
2.UDP 接收数据
步骤
1:创建接收端的socket对象(DatagramSocket)
2:创建一个数据包,用于接收数据
3:调用DatagramSocket对象的方法接牧数据
4:解析数据包,并把数据在拉制台显示
5:关闭接收端
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//创建接收端的socket对象(DatagramSocket)
//DatagramSocket (int port)构造数据报套接字并将其绑定到本地主机上的指定端口
DatagramSocket ds = new DatagramSocket(10086);
//创建一个数据包,用于接收数据
//DatagramPacket (byte[] buf,int length)构造一个DatagramPacket用于接收长度为Length数据包
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
//调用DatagramSocket对象的方法接牧数据
ds.receive(dp);
//解析数据包,并把数据在拉制台显示
/*
byte[] datas = dp.getData();
int len = dp.getLength();
String stringdata = new String(datas,0,len);
*/
System.out.println("数据是:" + new String(dp.getData(),0, dp.getLength()));
}
}
3.UDP发送数据接收数据案例
1.要求:UDP发送数据: 数据来自于键盘录入,直到输入的数据是886,发送数据结束
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建发送端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket();
//键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null){
if("886".equals(line)){
break;
}
//创建数据,并把数据打包、
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("10.67.112.222"),1111);
//调用DatagramSocket对象的方法发送方数据
ds.send(dp);
}
//关闭发送端
ds.close();
}
}
2. UDP接收数据: 因为接收端不知道发送端什么时候停止发送,故采用死循环接收
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//创建接收端的Socket对象(DatagramSocket)
DatagramSocket ds= new DatagramSocket(1111);
while (true){
//创建一个数据包,用于接收数据
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
//调用DatagramSocket对象的方法接收数据
ds.receive(dp);
//解析数据包,并把数据在控制台显示
System.out.println("数据是:" + new String(dp.getData(),0,dp.getLength()));
}
//应为是死循环所以不用关闭接收端
}
}
二,TCP协议:
TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端钙服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”
1.TCP发送数据
步骤
1:创建客户端的socket对象(Socket)
2:获取输出流,写数据
3:释放资源
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的socket对象(Socket)
//Socket (String host, int port)创建流套接字并将其连接到指定主机上的指定端口号
Socket s = new Socket("10.67.112.222",1111);
//获取输出流,写数据
//OutputStream getOutStream() 返回此套接字的输出流
OutputStream os = s.getOutputStream();
os.write("hello,tcp,我来了".getBytes());
//释放资源
s.close();
}
}
2. TCP接收数据
步骤
1:创建服务器端的Socket对象(ServerSocket)
2:获取输入流,读数据,并把数据显示在控制台
3:释放资源
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的Socket对象(ServerSocket)
//ServerSocket (int port) 创建绑定到指定端口的服务器套接字
ServerSocket ss = new ServerSocket(1111);
//Socket accept() 监听要连接到次套接字并接受它
Socket s = ss.accept();
//获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
System.out.println("数据是:" + new String(bys,0,len) );
//释放资源
ss.close();
}
}
3.TCP通信程序练习
1.客户端:发送数据,接收服务器反馈
/*
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket对象(Socket)
Socket s = new Socket("10.67.112.222",1111);
//获取输出流,写数据
OutputStream os = s.getOutputStream();
os.write("hello,java".getBytes());
//接受服务器反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
System.out.println("客户端:" + new String(bys,0,len) );
//释放资源
s.close();
}
}
/*
服务器:接收数据,给出反馈
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(1111);
//Socket accept() 监听要连接到次套接字并接受它
Socket s = ss.accept();
//获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
System.out.println("服务器:" + new String(bys,0,len) );
//给出反馈
OutputStream os = s.getOutputStream();
os.write("数据已收到".getBytes());
//释放资源
ss.close();
}
}
2.客户端:数据来自于键盘录入,知道输入的数据是886.发送数据结束
/*
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket对象(Socket)
Socket s = new Socket("10.67.112.222",1111);
//键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//封装输出对象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null){
if("886".equals(line)){
break;
}
//获取输出流,写数据
/*OutputStream os = s.getOutputStream();
os.write(line.getBytes());*/
bw.write(line);
bw.newLine();
bw.flush();
}
s.close();
}
}
/*
服务器:接收到的数据在控制台输出
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(1111);
//Socket accept() 监听要连接到次套接字并接受它
Socket s = ss.accept();
//获取输入流,读数据,并把数据显示在控制台
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
//关闭资源
ss.close();
}
}
3. 客户端:数据来自于键盘录入,知道输入的数据是886.发送数据结束
/*
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket对象(Socket)
Socket s = new Socket("10.67.112.222",1111);
//键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//封装输出对象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null){
if("886".equals(line)){
break;
}
//获取输出流,写数据
/*OutputStream os = s.getOutputStream();
os.write(line.getBytes());*/
bw.write(line);
bw.newLine();
bw.flush();
}
s.close();
}
}
/*
服务器:接收到的数据写入文本文件
*/
public class ServerDemo {
public static void main(String[] args) throws IOException{
//创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(1111);
//Socket accept() 监听要连接到次套接字并接受它
Socket s = ss.accept();
//获取输入流,读数据,并把数据显示在控制台
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//把数据写入文本
BufferedWriter bw = new BufferedWriter(new FileWriter("myNet.txt"));
String line;
while ((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
//关闭资源
ss.close();
bw.close();
}
}
4. 客户端:数据来自于文本,接受服务器反馈
/*
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket对象(Socket)
Socket s = new Socket("10.67.112.222",1111);
//创建字节输出流
BufferedReader br = new BufferedReader(new FileReader("ClientDemo.java"));
//封装输出对象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
//public void shutdownOutput() 给出一个结束标记使后面的程序不再等待
s.shutdownOutput();
//接受反馈
BufferedReader br2 = new BufferedReader(new InputStreamReader(s.getInputStream()));
String data = br2.readLine();
System.out.println("服务器反馈:" + data);
//释放资源
s.close();
br.close();
}
}
/*
服务器:接收到的数据写入文本文件,给出反馈,代码使用线程进行封装,为每一个客户端开启一个端口
*/
public class ServerDemo {
public static void main(String[] args) throws IOException{
//创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(1111);
while (true){
//Socket accept() 监听要连接到次套接字并接受它
Socket s = ss.accept();
//为每一个客户端开启一个端口
new Thread(new ServerThread(s)).start();
}
}
}
/*
ServerThread实现写入文件以及给出反馈
*/
public class ServerThread implements Runnable {
private Socket s;
public ServerThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
//获取输入流,读数据,并把数据显示在控制台
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//把数据写入文本
// BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
//解决名称冲突问题
int count = 0;
File file = new File("Copy["+count+"].java");
while (file.exists()){
count++;
file = new File("Copy["+count+"].java");
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
//读数据
String line;
while ((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
//给出反馈
BufferedWriter bw2 = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw2.write("文件上传成功");
bw2.newLine();
bw2.flush();
//释放资源
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}