本文主要介绍了网络编程中用户数据报协议UDP和传输控制协议,其中UDP是面向无连接的,传输效率高,安全性低,文中给出了通过socket实现UDP数据传输的过程。TCP是面向连接的传输协议,传输安全性较高,需要完成三次握手,文中给出了TCP客户端发送数据和服务器端接收数据的源代码,也介绍了多线程的方式实现TCP数据传输。
目录
- import java.io.IOException;
- import java.net.*;
-
- public class NetworkDemo01 {
- public static void main(String[] args) throws IOException {
- //创建socket对象
- DatagramSocket ds = new DatagramSocket() ;
-
- //创建数据并打包
- byte [] bytes = "Hello Java".getBytes() ;
- DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.102.1"),10086) ;
-
- //使用socket对象发送数据
- ds.send(dp);
- //关闭资源
- ds.close();
- }
- }
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
-
- public class NetworkDemo02 {
- public static void main(String[] args) throws IOException {
- //根据端口号创建socket对象
- DatagramSocket ds = new DatagramSocket(10086) ;
- //打包接收对象
- byte[] bytes = new byte[1024] ;
- DatagramPacket dp = new DatagramPacket(bytes,bytes.length) ;
-
- ds.receive(dp) ;
-
- System.out.println("接收到的数据是:" + new String(dp.getData(),0,dp.getLength()));
-
- //释放资源
- ds.close();
-
- }
- }
发送端socket程序:
- import java.io.*;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.InetAddress;
-
-
- public class SendDemo01 {
- public static void main(String[] args) throws IOException {
- DatagramSocket ds = new DatagramSocket() ;
-
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
- String line ;
-
- while((line=br.readLine()) != null){
- if(line.equals("886")){
- break ;
- }
- byte [] bytes = line.getBytes() ;
- DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.102.1"),10086) ;
-
- ds.send(dp);
- }
- ds.close();
- }
- }
接收端socket程序:
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
-
-
- public class ReceiveDemo {
- public static void main(String[] args) throws IOException {
- DatagramSocket ds = new DatagramSocket(10086) ;
- while(true) {
- byte[] bytes = new byte[1024];
- DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
-
- ds.receive(dp);
- System.out.println("接收到的数据是:" + new String(dp.getData(),0,dp.getLength()));
- }
-
- }
- }
客户端程序:
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
-
- public class ClientDemo01 {
- public static void main(String[] args) throws IOException {
- //获取客户端socket
- Socket socket = new Socket("192.168.102.1",10086) ;
-
- //获取输出流,写数据
- OutputStream os = socket.getOutputStream() ;
- os.write("hello java".getBytes());
-
- os.close();
- }
- }
服务器端程序:
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class ServerDemo01 {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10086) ;
- //监听客户端,并用此套接字接收它
- Socket s = ss.accept() ;
- //获取输入流,读数据并显示在控制台
- InputStream is = s.getInputStream() ;
- byte [] bytes = new byte[1024] ;
- int len ;
- while((len=is.read(bytes)) != -1){
- System.out.println(new String(bytes,0,len));
- }
- ss.close();
-
- }
- }
客户端:首先读取文件数据,然后通过socket对象获取输出流发送数据到服务器,并接收服务器的反馈。
- import java.io.*;
- import java.net.Socket;
-
- public class ClientDemo02 {
- public static void main(String[] args) throws IOException {
- //创建客户端socket对象
- Socket s = new Socket("192.168.102.1",10086) ;
-
- //创建字符缓冲输出流和输入流
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())) ;
- BufferedReader br = new BufferedReader(new FileReader("New\\src\\com\\learn\\java.txt")) ;
-
- //从文件读取并写入
- String line ;
- while((line=br.readLine()) != null){
- bw.write(line);
- bw.newLine();
- bw.flush();
- }
-
- s.shutdownOutput(); //提示服务器客户端发送完毕
-
- //接收服务器端的反馈
- BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s.getInputStream())) ;
- String data = bufferedReader.readLine() ;
- System.out.println("服务器端的反馈为:" + data);
-
- br.close();
- s.close();
-
-
- }
- }
服务器端:创建服务端套接字,并监听接收客户端信息,通过套接字对象创建服务器线程对象,并通过实现Runnable接口的方法启动线程。
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class ServerDemo02 {
- public static void main(String[] args) throws IOException {
- ServerSocket serverSocket = new ServerSocket(10086) ;
-
- while(true){
- Socket s = serverSocket.accept() ;
- ServerThread serverThread = new ServerThread(s);
- Thread t = new Thread(serverThread) ;
- t.start();
- }
- }
- }
服务器端线程实现方法:实现Runnable接口,并重写run()方法,该方法中包括套接字获取输入流接收文件和给予反馈。需要注意的是:防止文件命名冲突,需要设置文件是否存在判断,并做相应处理。
- import java.io.*;
- import java.net.Socket;
-
- 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())) ;
- //解决命名冲突问题
- int count = 0 ;
- File file = new File("New\\src\\com\\my\\copy" +count + ".txt") ;
- while (file.exists()){
- count ++ ;
- file = new File("New\\src\\com\\my\\copy" +count + ".txt") ;
- }
-
-
- BufferedWriter bw = new BufferedWriter(new FileWriter(file)) ;
- String line ;
- while((line=br.readLine()) != null){
- bw.write(line);
- bw.newLine();
- bw.flush();
- }
-
- //给出文件接收成功反馈
- BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())) ;
- bufferedWriter.write("文件上传成功");
- bufferedWriter.newLine();
- bufferedWriter.flush();
-
- s.close();
-
- }catch (IOException e){
- e.printStackTrace();
- }
- }
- }