网络编程基础
- 网络编程的目的:直接或间接的通过网络协议与其他计算机进行通信。
- 网络编程种有两个主要的问题:
(1)如何准确定位网络上的一台或多台主机,
(2)找到主机候如何高效地进行数据传输
在TCP/IP协议中IP
层主要负责主机的定位,由IP地址可以唯一确定Internet上的一台主机。网络编程一般不关心IP层是如何处理数据的。 - 目前较为流行的网络编程模型是客户端/服务器(C/S)结构,即通信双方一方作为服务器等待客户提出请求并予以响应,另一方则作为客户在需要服务时向服务器提出请求。
- 服务器一般作为守护进程始终运行,监听网络端口,一旦客户请求,就会启动一个独立线程来响应客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。
计算机网络:通过一定的物理设备将处于不同位置的计算机连接起来组成的网络
TCP/IP基本概念
- 主机名:网络地址的主机名,按照域名进行分级管理。例如:www. redmine.edu2act.org。
- IP地址:标识计算机等网络设备的网络地址,由4个8位的二进制数组成,中间以小数点分隔。例如:192.163.10.1。(由于IP地址不易记忆,引入网络域名来确认IP地址)
- 端口号:网络通信时同一机器上不同进程的标识。如80、21、23、25,其中1~1024为系统保留的端口号。
精确确定客户访问的是这台主机中的哪个应用程序
21 文件传输服务器(控制连接)(FTP)
23 运程终端服务器(TELNET)
25 简单邮件传输服务器(SMTP)
80 万维网服务器(HTTP) - 服务类型:网络的各种服务。如http、telnet、ftp、smtp。
服务类型是TCP层上面的应用层概念
。
确定好目标主机和应用程序后,就可进行网络传输。数据传递的两种最常见的形式:
-
TCP传输控制协议,
面向连接的、可靠的、基于字节流的传输层通信协议
首先要在网络两端建立安全连接,再进行数据传递,确保网络双方完整无误的传输数据 -
UDP用户数据报协议,一种
无连接
的传输层协议,提供面向事务的简单不可靠信息传送服务。
无需建立网络双方连接,直接发送数据包(包含目的地址信息),可能会因为网络问题导致数据传输失败等问题,但传输速度很快,常应用于局域网中传输数据 -
Java语言中,实现网络编程需要两个核心类包:
java.net.*
:网络类包,涵盖常用网络操作类
java.io.*
:数据消息传输包,在网络双方进行数据传递需要使用该包中的类
URL及应用
tips:
至于输入输出参考内存
:写进来的都是写入流,出去的就是输出流
- 常用构造方法:URL(String url)
常用方法:InputStream openStream()
打开当前URL连接的输入流
URLConnection openConnection()
建立URL网络连接
- URLConnection类:应用程序和URL之间的通信链接,用于读取和写入此URL引用的资源
对象建立方法:
(1)通过URL对象的openConnection()方法创建
(2)使用构造方法:URLConnection(URL url)
获得当前连接输入/输出流对象:getInputStream(), getOutputStream()
举一个栗子来感觉一下用法吧:
url = new URL("http://");
// 打开连接
URLConnection conn = url.openConnection();
// 得到输入流
InputStream is = conn.getInputStream();
// 关于IO流的用法和写法一定要熟悉
OutputStream os = new FileOutputStream("d:\\baidu.png");
byte[] buffer = new byte[2048];
int length = 0;
while (-1 != (length = is.read(buffer, 0, buffer.length))) {
os.write(buffer, 0, length);
}
is.close();
os.close();
-
HttpURLConnection类:特定支持HTTP协议的URLConnection
抽象类,不能直接实例化对象
对象建立方法:
(1)通过URL对象的openConnection()方法创建,强制转换为目标对象
(2)使用构造方法:HttpURLConnection(URL url)常用方法:(1)从URLConnection类继承的方法 (2)针对HTTP请求响应消息的特定方法,此处略
String sUrl = "http://pic42.nipic.com/20140608/12504116_194242259000_2.jpg";
URL url = new URL(sUrl); // 创建URL对象
InputStream in = url.openStream(); // 获得网络输入流
// 创建文件输出流
FileOutputStream out = new FileOutputStream(“cat.jpg");
int b;
while ((b = in.read()) != -1) {
out.write(b); // 写入文件
}
// 关闭输入输出流
out.close(); in.close();
举例:获取服务器HTTP响应消息(消息头和消息主体)
URL url = new URL(rootUrl); // 创建Url对象
// 得到URLConnection连接对象
URLConnection conn = url.openConnection();
HttpURLConnection hc = (HttpURLConnection) conn;
// 获得响应消息头
conn.getContentType();
conn.getContentLength();
conn.getContentEncoding();
// 获得HTTP消息状态码
hc.getResponseCode();
hc.getResponseMessage();
// 获得HTTP响应消息主体
hc.getContent();
基于套接字的Java网络编程
-
客户端与服务器建立连接后,连接两端会建立一个虚拟“线缆”,在网络编程中称之为
Socket(套接字)
; 其后在网络两端传输数据都是通过Socket进行的。
(1)Socket借助于IP地址和端口号,对应某一台主机中的某一个应用程序
(2)Socket的主要作用:维护网络连接、在网络双方传输数据 -
Socket类:客户端套接字类。实现客户端向服务器发送数据、接收服务器数据等功能;实现服务器端向客户端发送数据、接收客户端数据等功能
构造方法:
Socket(InetAddress address, int port);
Socket(String host, int port); -
客户端一般编写步骤:(1)
连接
服务器端 (2)数据传输
(3)关闭
连接,释放资源
服务器端一般编写步骤:(1)创建
服务器端ServerSocket对象 (2)通过accept()方法获取Socket对象 (连接
)(3)数据传输
(4)释放资源
示例1:客户端与服务器端的单次通信,客户端发,服务器收注意运行时,应先运行服务器端
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class client1_demo1_xxx {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.连接到服务器端
Socket socket = new Socket("127.01.01", 9999);
//2.数据传输向服务器发送数据
OutputStream os = socket.getOutputStream();
String content = "你好,我是客户端";
os.write(content.getBytes());
//3.关闭连接,释放资源
os.close();
socket.close();
}
}
/*
1.getBytes()方法得到一个操作系统默认的编码格式的字节数组
2.可以通过new String(byte[], decode)使用指定的编码decode来将byte[]解析成字符串
String s = new String(b_utf8, "UTF-8");
*/
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 客户端与服务器端的单次通信,客户端发,服务器收
* */
public class server1_demo1_xxx {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
// 1.创建服务器端ServerSocket对象
ServerSocket server = new ServerSocket(9999);
System.out.println("等待连接");
// 2.通过accept()获取Socket对象
Socket socket = server.accept();
System.out.println("连接成功");
// 3.数据传输
// 接受客户端的数据
InputStream is;
is = socket.getInputStream();
byte[] result = new byte[1024];
is.read(result);
String s1 = new String(result);
System.out.println(s1);
// 4.释放资源
is.close();
socket.close();
server.close();
}
}
示例2:客户端与服务器端的单次双向通信
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 客户端与服务器端的单次双向通信
* flush()强制把数据输出,清空缓存区
* */
public class client2_demo2_xxx {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.01.01", 9999);
OutputStream os = socket.getOutputStream();
//向服务器发送数据
String content = "你好,我是客户端";
os.write(content.getBytes());
os.flush();
//收到服务器的数据
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
is.read(b);
System.out.println(new String(b));
os.close();
socket.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class server2_demo2_xxx {
public static void main(String[] args) throws IOException {
// 1.创建服务器端ServerSocket对象
ServerSocket server = new ServerSocket(9999);
System.out.println("等待连接");
// 2.通过accept()获取Socket对象
Socket socket = server.accept();
System.out.println("连接成功");
// 3.数据传输
// 接受客户端的数据
InputStream is;
is = socket.getInputStream();
byte[] result = new byte[1024];
is.read(result);
String s1 = new String(result);
System.out.println(s1);
// 向客户端发送数据
OutputStream oStream = socket.getOutputStream();
oStream.write(new String("我是服务器,我收到你的信息了").getBytes());
oStream.flush();
is.close();
socket.close();
server.close();
}
}
示例3:客户端先发后收,服务器:先收后发
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 客户端先发后收,服务器:先收后发
* */
public class client3_demo3_xxx {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Socket socket = new Socket("127.01.01", 9999);
OutputStream os = socket.getOutputStream();
String content = "你好,我是客户端";
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(content);
dos.flush();
//收到服务器的数据
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
is.read(b);
System.out.println(new String(b));
os.close();
socket.close();
}
}
/*
* DataOutputStream数据输出流允许将引用程序将基本Java数据类型写到基础输出流中
* readUTF()---从数据输入流中读取用UTF-8格式编码的UniCode字符格式的字符串.
*/
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.zip.DeflaterInputStream;
public class server3_demo3_xxx {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
// 1.创建服务器端ServerSocket对象
ServerSocket server = new ServerSocket(9999);
System.out.println("等待连接");
// 2.通过accept()获取Socket对象
Socket socket = server.accept();
System.out.println("连接成功");
// 3.数据传输
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is);
String s1 = dis.readUTF();
System.out.println(s1);
// 向客户端发送数据
OutputStream oStream = socket.getOutputStream();
oStream.write(new String("我是服务器,我收到你的信息了").getBytes());
oStream.flush();
is.close();
socket.close();
server.close();
}
}
示例4:客户端与服务器的多次双向通信
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 客户端与服务器的多次双向通信
*/
public class Client1 {
public static void main(String[] args) throws Exception {
// 1、连接服务器10.7.90.94
Socket socket=new Socket("127.0.0.1", 6666);
// 2、数据传输
// 向服务器发送数据
OutputStream os=socket.getOutputStream();
String content="你好,我是客户端1";
os.write(content.getBytes());
os.flush();
// 收到服务器的数据
InputStream is=socket.getInputStream();
byte[] b=new byte[1024];
is.read(b);
System.out.println(new String(b));
// 3、关闭连接,释放资源
os.close();
socket.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 客户端与服务器的多次双向通信
*/
public class Client2 {
public static void main(String[] args) throws Exception {
// 1、连接服务器:10.7.90.94
Socket socket=new Socket("127.0.0.1", 6666);
// 2、数据传输
// 向服务器发送数据
OutputStream os=socket.getOutputStream();
String content="exit";
os.write(content.getBytes());
os.flush();
// 收到服务器的数据
InputStream is=socket.getInputStream();
byte[] b=new byte[1024];
is.read(b);
System.out.println(new String(b));
// 3、关闭连接,释放资源
os.close();
socket.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {
public static void main(String[] args) throws Exception {
// 1、创建ServerSocket对象,启动服务器
ServerSocket server = new ServerSocket(6666);
System.out.println("等待连接");
InputStream is;
OutputStream os;
int i = 0;
while (true) {
// i++;
// if (i == 68) {
// break;
// }
// 2、等待客户端连接,处于阻塞
Socket socket = server.accept();
System.out.println("连接成功");
// 3、数据传输
// 接收数据
is = socket.getInputStream();
byte[] result = new byte[1024];
is.read(result);
String s1 = new String(result, "UTF-8");
System.out.println(s1);
// 发送数据
os = socket.getOutputStream();
os.write(new String("我是服务器端").getBytes());
os.flush();
is.close();
os.close();
socket.close();
if (s1.startsWith("exit")) {
break;
}
}
//4、关闭连接
server.close();
}
}
实例5: 实现服务器端多线程
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 实现服务器端多线程
*/
public class Client1 {
public static void main(String[] args) throws Exception {
Socket socket=new Socket("127.0.0.1", 8888);
OutputStream os=socket.getOutputStream();
String content="我是客户端1";
os.write(content.getBytes());
os.flush();
Thread.sleep(5000);
InputStream is=socket.getInputStream();
byte[] b=new byte[1024];
is.read(b);
System.out.println(new String(b));
os.close();
socket.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 实现服务器端多线程
*/
public class Client2 {
public static void main(String[] args) throws Exception {
Socket socket=new Socket("127.0.0.1", 8888);
OutputStream os=socket.getOutputStream();
String content="我是客户端2";
os.write(content.getBytes());
os.flush();
Thread.sleep(5000);
InputStream is=socket.getInputStream();
byte[] b=new byte[1024];
is.read(b);
System.out.println(new String(b));
os.close();
socket.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
class ServerTread extends Thread {
private Socket socket;
public ServerTread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
InputStream is;
OutputStream os;
try {
System.out.println(this.getName());
is = socket.getInputStream();
byte[] result = new byte[1024];
is.read(result);
String s1 = new String(result, "UTF-8");
System.out.println(s1);
os = socket.getOutputStream();
os.write(new String("我是服务器端").getBytes());
os.flush();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8888);
int i = 0;
while (true) {
System.out.println("等待监听");
Socket socket = server.accept();
System.out.println("我是服务器端");
i++;
if (i == 5) {
break;
}
new ServerTread(socket).start();
}
server.close();
}
}
实例六:练习:实现客户端键盘多次输入,服务器端接收并打印,带缓冲的字符流+循环输入,如果输入以exit开头的内容,退出
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
* 实现客户端键盘多次输入,服务器端接收并打印,带缓冲的字符流+循环输入,如果输入exit,退出
*/
public class Client1 {
public static void main(String[] args) throws Exception {
// Scanner对象实现键盘输入
Scanner scanner = new Scanner(System.in);
Socket socket = new Socket("127.0.0.1", 9000);
OutputStream os = socket.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
//System.out.println("请输入用户名:");
while (true) {
String input = scanner.nextLine();
// 带缓冲的字符流,使用低级的字节流来构建
writer.write(input);
input = input + '\n';
writer.flush();
if(input.startsWith("exit")) {
break;
}
}
writer.close();
socket.close();
}
}
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 Server {
public static void main(String[] args) throws Exception {
ServerSocket server=new ServerSocket(9000);
System.out.println("等待连接");
Socket socket=server.accept();
System.out.println("连接成功");
InputStream is=socket.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(is));
while(true) {
String result = reader.readLine();
if(result == null) {
break;
}
System.out.println("你的输入是:"+result);
}
is.close();
socket.close();
server.close();
}
}
其他知识
- InetAddress类
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressDemo {
public static void main(String[] args) throws Exception {
InetAddress address=InetAddress.getLocalHost();
System.out.println(address.getHostAddress());//返回文本显示中的IP地址字符串。
System.out.println(address.getHostName());//获取此IP地址的主机名。
}
}
- 流的简单应用:从网上下载一个图片
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
public class Demo1 {
public static void main(String[] args) throws IOException {
String url_str="https://www.baidu.com/img/flexible/logo/pc/result.png";
URL url=new URL(url_str);
// URLConnection conn=url.openConnection();
// InputStream is=conn.getInputStream();//����ڴ�
InputStream is=url.openConnection().getInputStream();
OutputStream os=new FileOutputStream("d:\\demo\\a20220222.png");
int n=-1;
while((n=is.read())!=-1) {
os.write(n);
}
is.close();
os.close();
System.out.println("下载成功");
}
}
基于UDP网络编程
上述代码均为基于TCO传输协议的的网络编程。此处介绍UDP相关知识
-
TCP与UDP连接的区别:
-
UDP传输协议通过数据包方式向服务器发送数据,在数据包中包含
服务器的IP信息、端口信息
等内容。 -
DatagramSocket类:客户端/服务器端网络Socket端口对象
构造方法:
(1)DatagramSocket(); // 创建一个空的Socket对象
(2)DatagramSocket(int port); // 创建指定监听端口的Socket对象
常用方法:
(1)void send(DatagramPacket p); // 发送数据报文
(2)void receive(DatagramPacket p); // 接收数据报文 -
DatagramPacket类:数据报文对象
构造方法:
DatagramPacket(byte[] buf, int len);
// 用空数组创建对象,用来接收数据
DatagramPacket(byte[] buf, int offset, int len);
// 接收数据的特定部分
DatagramPacket(byte[] buf, int len, InetAddress addr, int port);
// 包含数据的数组创建对象,用来发送数据,同时指明数据目的地和目标端口号
DatagramPacket(byte[] buf, int offset, int len, InetAddress addr, int port);
// 发送数据的指定部分
- 客户端一般编写步骤:(1)创建DatagramSocket对象 (2)封装请求数据 (3)创建DatagramPacket对象 (4)发送请求
服务器端一般编写步骤:(1)创建DatagramSocket对象,监听特定端口 (2)创建DatagramPacket对象(空缓冲区) (3)封装服务器响应数据,创建DatagramPacket对象 (4)发送服务器响应给指定客户端
示例1:单向发送、接收
package udp1__xxx;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
//发送端
public class Sender {
public static void main(String[] args) throws IOException {
// 1.创建DategramSocket对象,不需要指定端口
DatagramSocket socket = new DatagramSocket();
// 2.【数据报中只允许字节数组】, 准备字节数组
byte[] input = "hellow.sever".getBytes();
// 3.创建DatagramPacket对象,需要指定接收方的ip,端口号
DatagramPacket packet = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.0.1"), 8000);
// 4.发送数据
socket.send(packet);
// 5.关闭连接
socket.close();
}
}
package udp1__xxx;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/*
* 单向发送、接收
* */
public class Recevier {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
// 1.接收方、创建DatagramSocket对象,需要指定端口号
DatagramSocket socket = new DatagramSocket(8000);
byte[] data = new byte[1024];
// 2.DatagramPacket
DatagramPacket packet = new DatagramPacket(data, data.length);
System.out.println("等待接收");
// 3.阻塞式接受
socket.receive(packet);
System.out.println("接收完成");
// 4.分析数据
byte[] result = packet.getData();
System.out.println(new String(result));
// 5.关闭Socket
socket.close();
}
}
示例2:学生端先发送,后接收; 教师端先接受,后发送
package udp2_xxx;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/*
* 学生端先发送,后接收
* 教师端先接受,后发送
* */
public class Student {
public static void main(String[] args) throws IOException {
// 1.创建DategramSocket对象
DatagramSocket socket = new DatagramSocket(9000);
// 2.【数据报中只允许字节数组】, 准备字节数组
byte[] input = "hellow.imstudent".getBytes();
// 3.创建DatagramPacket对象,需要指定接收方的ip,端口号
DatagramPacket packet = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.01"), 8000);
// 4.发送数据
socket.send(packet);
byte[] data = new byte[1024];
// 2.DatagramPacket
DatagramPacket packet2 = new DatagramPacket(data, data.length);
System.out.println("等待接收");
// 3.阻塞式接受
socket.receive(packet2);
System.out.println("接收完成");
// 4.分析数据
byte[] result = packet2.getData();
System.out.println(new String(result));
// 5.关闭Socket
socket.close();
}
}
package udp2_xxx;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class teacher {
public static void main(String[] args) throws IOException {
// 1.接收方、创建DatagramSocket对象,需要指定端口号
DatagramSocket socket = new DatagramSocket(8000);
byte[] data = new byte[1024];
// 2.DatagramPacket
DatagramPacket packet = new DatagramPacket(data, data.length);
System.out.println("等待接收");
// 3.阻塞式接受
socket.receive(packet);
System.out.println("接收完成");
// 4.分析数据
byte[] result = packet.getData();
System.out.println(new String(result));
// 5.关闭Socket
byte[] input = "hellow.imteacher".getBytes();
// 3.创建DatagramPacket对象,需要指定接收方的ip,端口号
DatagramPacket packet2 = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.01"), 9000);
// 4.发送数据
socket.send(packet2);
// 5.关闭连接
socket.close();
}
}
示例3:键盘输入多次向教师端发送数据
package udp3_xxx;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.zip.InflaterInputStream;
/*
* 键盘输入多次发送
* */
public class student {
public static void main(String[] args) throws IOException {
// 1.创建DategramSocket对象
DatagramSocket socket = new DatagramSocket(9000);
// 2. 准备字节数组【数据报中只允许字节数组】
System.out.println("你的名字:");
while(true) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String result = br.readLine();
byte[] input = result.getBytes();
// 3.创建DatagramPacket对象,需要指定接收方的ip,端口号
DatagramPacket packet = new DatagramPacket
(input, input.length, InetAddress.getByName("127.0.01"), 8000);
// 4.发送数据
socket.send(packet);
if(result.equals("bye")) {
break;
}
}
byte[] data = new byte[1024];
// 2.DatagramPacket
DatagramPacket packet2 = new DatagramPacket(data, data.length);
System.out.println("等待接收");
// 3.阻塞式接受
socket.receive(packet2);
System.out.println("接收完成");
// 4.分析数据
byte[] result = packet2.getData();
System.out.println(new String(result));
// 5.关闭Socket
socket.close();
}
}
package udp3_xxx;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class teacher {
public static void main(String[] args) throws IOException {
// 1.接收方、创建DatagramSocket对象,需要指定端口号
DatagramSocket socket = new DatagramSocket(8000);
byte[] data = new byte[1024];
// 2.DatagramPacket
while(true) {
DatagramPacket packet = new DatagramPacket(data, data.length);
System.out.println("等待接收");
// 3.阻塞式接受
socket.receive(packet);
System.out.println("接收完成");
// 4.分析数据
byte[] result = packet.getData();
String str = new String(result);
System.out.println(str);
if(str.equals("")) {
break;
}
}
byte[] input = "hellow.imteacher".getBytes();
// 3.创建DatagramPacket对象,需要指定接收方的ip,端口号
DatagramPacket packet2 = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.01"), 9000);
// 4.发送数据
socket.send(packet2);
// 5.关闭连接
socket.close();
}
}
示例4:学生端、老师端,均启动两个子线程
package udp3_xxx;
import java.net.SocketException;
public class teachers {
public static void main(String[] args) throws SocketException {
new Thread(new ChatRecevier(9000, "小孩说")).start();
new Thread(new ChatSender("127.0.0.1", 8000)).start();
}
}
package udp3_xxx;
import java.net.SocketException;
/*
* 学生端、老师,都启动两个子线程
* */
public class students {
public static void main(String[] args) throws SocketException {
new Thread(new ChatRecevier(8000, "老师说")).start();
new Thread(new ChatSender("127.0.0.1", 9000)).start();
}
}
package udp3_xxx;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class ChatSender implements Runnable{
DatagramSocket socket;
String ip;
int port;
BufferedReader br;
public ChatSender(String ip, int port) throws SocketException {
socket = new DatagramSocket();
this.ip = ip;
this.port = port;
this.br = new BufferedReader(new InputStreamReader(System.in));
}
@Override
public void run() {
while(true) {
String result = null;
try {
result = br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] input = result.getBytes();
// 3.创建DatagramPacket对象,需要指定接收方的ip,端口号
DatagramPacket packet = null;
try {
packet = new DatagramPacket
(input, input.length, InetAddress.getByName(this.ip), this.port);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 4.发送数据
try {
socket.send(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(result.startsWith("bye")) {
break;
}
}
}
}
package udp3_xxx;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatRecevier implements Runnable {
DatagramSocket socket;
String form;
public ChatRecevier(int port, String form) throws SocketException {
socket = new DatagramSocket(port);
this.form = form;
}
public void run() {
while (true) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
socket.receive(packet);
byte[] result = packet.getData();
String strs = new String(result);
System.out.println(form + strs);
if (strs.startsWith("bye")) {
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}