网络编程-Socket通信实现服务器与客户端互传文件(JAVA语言实现)

网络编程-Socket通信实现服务器与客户端互传文件(JAVA语言实现)

在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换.

网络编程三要素:ip地址、端口、协议

ip地址:

每台计算机指定的一个标识符,127.0.0.1是回送地址,可以代表本机地址 ,一般用来测试使用

ipconfig:命令行中查看本机地址

ping ip地址:检查网络是否连通

端口

两个应用程序的通信。IP地址是可以唯一标识网络中的设备,端口就是可以唯一标识设备中的应用程序。

端口号:用两个字节表示的整数,它的取值范围是0-65535.其中0-1023之间的端口号用于一些知名的网络服务和应用,普遍的应用程序要使用1024以上。

协议:

连接和通信的规则称为网络的通信协议.

常见的协议UDP和tcp

UDP:用户数据报协议.

无连接的通信协议,即使在传输数据的时候,发送端和接收端不建立连接.

消耗资源小,通信效率高.

UDP适用于音频,视频和普通数据的传输.

TCP:传输控制协议

是面向连接的同学,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据.

两台计算机无差错的数据传授.

需要经过三次握手,四次挥手

三次握手:

  • 客户端向服务器端发出连接请求,等待服务确认

  • 服务器端向客户端回送一个响应,通知客户端收到了连接请求

  • 客户端再次向服务器端发送确认信息,确认连接

TCP是可以保证数据的安全的传输,上传文件,下载文件等等

Socket实现客户端向服务器发送文件

在这里插入图片描述

在这里插入图片描述

先运行服务器,再运行客户端部分的代码。

serverDemo02.java

package demo02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo02 {
    public static void main(String[] args) throws Exception{
        //创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //监听客户端连接

        Socket socket = serverSocket.accept();//阻塞式监听会一直等待客户端连接
        //获取输入流
        InputStream is = socket.getInputStream();

        //文件输出
        File file=new File("E:/receive3.jpg");//接收文件地址
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {

            fos.write(buffer,0,len);
        }//关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

clientDemo02.java

package  demo02;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class clientDemo02 {
    public static void main(String[] args) throws Exception{

        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        OutputStream os=socket.getOutputStream();
        //读取文件流
        
        File file=new File("E:/enginePractise/netStydy/test.jpg");//传输文件地址
        //也可以传输txt文件或其他文件,但是客户端服务器端都要更改相应文件后缀名
        FileInputStream fis = new FileInputStream(file);
        //写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer,0,len);

        }
        //关闭资源
        fis.close();
        os.close();
        socket.close();

    }
}



Socket实现服务器端向客户端发送文件

先运行服务器端,再运行客户端代码。

serverDemo03.java

package demo03;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo03 {
    public static void main(String[] args) throws Exception{
        //创建服务
        ServerSocket serverSocket = new ServerSocket(9000);

        //监听客户端连接
        Socket socket = serverSocket.accept();//阻塞式监听会一直等待客户端连接
        OutputStream os=socket.getOutputStream();
        //Socket socket=serverSocket.accept();
        //读取文件流

        File file=new File("upload.txt");
        FileInputStream fis = new FileInputStream(file);

        //写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer,0,len);
            //System.out.println(len);

        }


        //关闭资源
        fis.close();
        os.close();

       socket.close();
        serverSocket.close();
    }
}

clientDemo03.java

package demo03;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class clientDemo03 {
    public static void main(String[] args) throws Exception{

        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        //获取输入流
        InputStream is = socket.getInputStream();
        //文件输出
        File file=new File("receiveTest.txt");

        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            //System.out.println(len+"client");
            fos.write(buffer,0,len);
        }//关闭资源
        fos.close();
        is.close();
        socket.close();
    }
}



Socket实现客户端向服务器多次发送文件

通过上面两个例子,我们实现了服务器与客户端之间的发送文件,但是我们会发现一个问题,每次运行完客户端后,客户端和服务器端就终止了,下一次传送文件,又要重新运行服务器端,再运行客户端,但有一种方法,就是只运行一次服务器端,可以一直重复运行客户端。达到一直发送文件的效果。

先运行服务器端,再重复运行客户端。

ServerDemo04.java

package demo04;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ServerDemo04 {
    public static void main(String[] args) throws Exception{
        //创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        ThreadPoolExecutor pool=new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        while(true){
            Socket accept = serverSocket.accept();
            ThreadSocket ts=new ThreadSocket(accept);
//			new Thread(ts).start();
            pool.submit(ts);
        }
        //监听客户端连接
        //Socket socket = serverSocket.accept();//阻塞式监听会一直等待客户端连接

    }
}

ThreadSocket.java

package demo04;

import java.io.*;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ThreadSocket implements Runnable{
    private Socket accept;
    public ThreadSocket(Socket accept){
        this.accept=accept;
    }
    @Override
    public void run() {
        //获取输入流
        InputStream is = null;
        try {
            is = accept.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //文件输出
        File file=new File(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()).toString()+".jpg");//使得每次运行产生的文件名都不相同
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        byte[] buffer = new byte[1024];
        int len;
        while (true) {
            try {
                if (!((len = is.read(buffer)) != -1)) break;
                fos.write(buffer,0,len);
            } catch (IOException e) {
                e.printStackTrace();
            }


        }//关闭资源
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            accept.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //socket.close();
        //serverSocket.close();
    }
}

clientDemo04

package demo04;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class clientDemo04 {
    public static void main(String[] args) throws Exception{

        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        OutputStream os=socket.getOutputStream();
        //读取文件流

        File file=new File("E:/enginePractise/netStydy/test.jpg");
        FileInputStream fis = new FileInputStream(file);
        //写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer,0,len);

        }
        //关闭资源
        fis.close();
        os.close();
        socket.close();

    }
}



Socket实现客户端和服务器端互传文件

其实这个也不难,上面几个例子看懂了之后,直接在服务器端和客户端都写上读取写入的方法(就是把上面前两个例子都写上就行了),再另写一个调用例子来运行就好了。

总结

本博客仅作为技术交流和本人学习记录使用,有问题欢迎大家指正。多多交流技术才能更高的理解掌握。

  • 3
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问题。首先,我需要说明的是,我是一个语言模型,没有实际的界面和Socket编程能力。但是,我可以给你一些指导和建议,帮助你完成这个任务。 要使用Java编写gui界面的Socket聊天室,你需要了解以下几个方面的知识: 1. Java GUI编程。Java提供了多种GUI编程框架,比如Swing、JavaFX等。你需要选择其中一种框架,并学习如何创建GUI窗口、添加组件、处理事件等。 2. Socket编程。Socket编程是实现网络通信的重要技术,你需要学习如何创建Socket对象、建立连接、发送和接收数据等。 3. 多线程编程。为了实现服务器端同时处理多个客户端的请求,你需要使用多线程编程技术。 下面是一个简单的示例代码,可以帮助你了解如何使用Java Socket编程和GUI编程实现一个简单的聊天室。 Server.java ```java import java.net.*; import java.io.*; import java.util.*; public class Server { private ServerSocket serverSocket; private List<ClientHandler> clients; public Server(int port) { try { serverSocket = new ServerSocket(port); clients = new ArrayList<>(); } catch (IOException e) { e.printStackTrace(); } } public void start() { while (true) { try { Socket socket = serverSocket.accept(); ClientHandler handler = new ClientHandler(socket); clients.add(handler); handler.start(); } catch (IOException e) { e.printStackTrace(); } } } private class ClientHandler extends Thread { private Socket socket; private BufferedReader in; private PrintWriter out; public ClientHandler(Socket socket) { this.socket = socket; try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); } catch (IOException e) { e.printStackTrace(); } } public void run() { try { String name = in.readLine(); System.out.println(name + " joined the chat room."); broadcast(name + " joined the chat room."); String message; while ((message = in.readLine()) != null) { System.out.println(name + ": " + message); broadcast(name + ": " + message); } } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); clients.remove(this); broadcast("Someone left the chat room."); } catch (IOException e) { e.printStackTrace(); } } } private void broadcast(String message) { for (ClientHandler handler : clients) { handler.out.println(message); } } } public static void main(String[] args) { Server server = new Server(12345); server.start(); } } ``` Client.java ```java import java.net.*; import java.io.*; import javax.swing.*; public class Client { private String name; private Socket socket; private BufferedReader in; private PrintWriter out; public Client(String name, String hostname, int port) { this.name = name; try { socket = new Socket(hostname, port); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); out.println(name); } catch (IOException e) { e.printStackTrace(); } } public void start() { JFrame frame = new JFrame(name); JTextArea textArea = new JTextArea(); JTextField textField = new JTextField(); JButton sendButton = new JButton("Send"); textArea.setEditable(false); sendButton.addActionListener(e -> { String message = textField.getText(); out.println(message); textField.setText(""); }); frame.add(textArea, "Center"); frame.add(textField, "South"); frame.add(sendButton, "East"); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); new Thread(() -> { String message; try { while ((message = in.readLine()) != null) { textArea.append(message + "\n"); } } catch (IOException e) { e.printStackTrace(); } }).start(); } public static void main(String[] args) { String name = JOptionPane.showInputDialog("Enter your name:"); Client client = new Client(name, "localhost", 12345); client.start(); } } ``` 这个聊天室程序中,Server.java实现服务器端的功能,Client.java实现客户端的功能。你可以根据需要进行修改和扩展。 希望这些代码能够对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值