Java中Socket通信的知识回顾---学习笔记

两台计算机进行通信的基本前提:

(1)IP地址:

每台计算机都有自己独一无二的IP地址,根据IP地址判断与哪台计算机进行通信。

(2)端口号:

每个应用程序都有自己专属的端口,根据端口号判断与计算机中的哪个应用程序进行通信。

说明:

<1>用于区分不同应用程序

<2>端口号的范围:0-65535,其中0-1023是为系统保留的端口号

<3>常用的协议的端口号:

http:80

ftp:21

telnet:23

<4>IP地址+端口号=Socket,Socket是TCP和UDP通信的基础

(3)协议:

好比是两个计算机通信的共同的语言,只用同时用这种协议才能够听懂对方说的话。

TCP/IP协议:是目前世界上应用最为广泛的协议,TCP/IP协议是传输层的协议,HTTP超文本传输协议,FTP文件传输协议,SMTP简单邮件传送协议,Telnet远程登录服务是应用层协议。

TCP:传输控制协议

IP:互联网协议

Java中提供的网络功能有四大类:

(1)InetAddress:用于标识网络上的硬件资源(就是IP地址的相关信息)

(2)URL:同一资源定位符,通过URL可以直接读取和写入网络上的数据

(3)Socket:使用TCP协议实现网络通信的Socket相关的类

(4)Datagram:使用UDP协议,将数据保存到数据报中,通过网络进行通信

注意:

TCP协议:是面向连接的,可靠的,有序的,以字节流的方式发送数据

UDP协议:是无连接的,不可靠的,无序的,速度比较快,以数据报作为数据传输的载体,进行数据传输时,首先要将传输的数据定义成数据报(Datagram),在数据报中指明数据所要到达的Socket(主机地址和端口号),然后再将数据报发送出去。

基于TCP的Socket通信:

(1)服务器端的实现步骤:

<1>创建ServerSocket,指定端口号

<2>调用ServerSocket的accept()方法(该方法为阻塞方法,直到有客户端连接进来才会执行该方法之后的代码),等待客户端的连接,当有客户端连接后就会返回一个Socket实例

<3>调用Scoket实例的getInputStream()方法,读取客户端发送过来的信息

<4>调用Socket实例的getOutputStream()方法,向客户端写入服务器发送给该客户端的信息

<5>关闭所有资源

(2)客户端实现步骤:

<1>创建Socket对象,并指明服务器的IP地址(或主机名)和端口号

<2>调用Socket实例的getOutputStream()方法,向服务器发送内容

<3>调用Socket实例的getInputStream()方法,接收服务器发送来的信息

<4>关闭所有资源

注意:

在使用socket进行TCP通信时,对于同一个Socket,如果关闭了输出流,

则与该输出流关联的socket也会被关闭,所以一般不用关闭流,直接关闭socket即可。

下面一个多客户端(多线程)与服务器通信的例子来说明一下基于TCP协议的Socket通信使用方法:

服务器端代码:

package com.socket.serversocket;

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

public class Serversocket {

    public static void main(String[] args) {

            ServerSocket serversocket;
            int count = 0;
            try {
                serversocket = new ServerSocket(8080);
                System.out.println("服务器已经启动,等待客户端的连接。。。。");
                while(true){
                    Socket socket = serversocket.accept();
                    new ServerThread(socket).start();
                    count++;
                    System.out.println("客户端的IP:"+socket.getInetAddress().getHostAddress());
                    System.out.println("连接的客户端的总数:"+count);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }

    }

}
package com.socket.serversocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ServerThread extends Thread{
    Socket socket = null;
    public ServerThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;
            while((line = br.readLine())!=null){
                System.out.println("我是服务器,客户端发来的信息是:"+line);
            }
            socket.shutdownInput();//关闭socket的输入流

            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            pw.write("欢迎访问服务器");
            socket.shutdownOutput();//关闭socket的输出流

            //关闭资源
            br.close();
            pw.close();
            socket.close();//注意:在使用socket进行TCP通信时,对于同一个Socket,如果关闭了输出流,
            //则与该输出流关联的socket也会被关闭,所以一般不用关闭流,直接关闭socket即可

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

客户端代码:

package com.socket.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("localhost",8080);
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os);
            String s = "用户名:admin;密码:123";
            pw.write(s);
            pw.flush();//因为PrintWriter是字符流,所以在写入完成后一定要调用字符流的flush()方法,冲刷缓冲区保证所有内容已经从流里写出去了
            socket.shutdownOutput();

            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line = null;
            while((line = br.readLine())!=null){
                System.out.println("我是客户端,接收到服务器发来的信息为:"+line);
            }
            socket.shutdownInput();
            //关闭资源
            br.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

程序运行结果:

基于UDP的Socket通信

(1)服务器端实现步骤:

<1>创建DatagramSocket,指定端口号

<2>创建DatagramPacket

<3>接收客户端发送的数据信息

<4>读取数据

(2)客户端实现步骤:

<1>定义发送信息

<2>创建DatagramPacket,包含将要发送的信息

<3>创建DatagramSocket

<4>发送数据

下面是一个客户端(单线程)与服务器之间的信息交互例子,可以看出基于UDP的Socket通信的使用步骤:

服务器端代码:

package com.udpServer;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Server {
    public static void main(String[] args) {
        try {
            //1.创建服务器端DatagramSocket,指定端口
            DatagramSocket socket = new DatagramSocket(8080);
            //2.创建数据报,用于接收客户端发送的数据
            byte[] data = new byte[1024];//创建字节数组,指定接收的数据包的大小
            DatagramPacket packet = new DatagramPacket(data, data.length);
            //3.接收客户端发送的数据
            System.out.println("服务器端已经启动,等待客户端连接。。。");
            socket.receive(packet);//此方法在接收到数据之前一直阻塞
            //4.读取数据
            String info = new String(data,0,packet.getLength());
            System.out.println("我是服务器,客户端说:"+info);

            /*
             * 服务器端响应客户端
             *
             */
            //1.定义客户端的地址,端口号,数据
            InetAddress address = packet.getAddress();
            int port = packet.getPort();
            byte[] data2 = "欢迎访问服务器!".getBytes();
            //2.创建数据报,包含响应的数据信息
            DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
            //3.响应客户端
            socket.send(packet2);
            //4.关闭资源
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

客户端代码:

package com.udpClient;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * 客户端
 * 2015年8月28日 下午2:19:51
 * @author 张耀晖
 *
 */
public class Client {
    public static void main(String[] args) {

        try {
            /*
             * 向服务器端发送数据
             */
            //1.定义服务器的地址,端口号,数据
            InetAddress address = InetAddress.getByName("localhost");
            int port = 8080;
            byte[] data = "用户名:admin;密码:123".getBytes();
            //2.创建数据报,包含发送的数据信息
            DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
            //3.创建DatagramSocket对象
            DatagramSocket socket = new DatagramSocket();
            //4.向服务器端发送数据报
            socket.send(packet);

            /*
             * 接收服务器端相应的数据
             *
             */
            //1.创建数据报,用于接收服务器相应的数据
            byte[] data2 = new byte[1024];
            DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
            //2.接收服务器端响应的数据信息
            socket.receive(packet2);
            //3.读取数据
            String reply = new String(data2,0,packet2.getLength());
            System.out.println("我是客户端,服务器说:"+reply);
            //4.关闭资源
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行结果演示:

下面是多个客户端(多线程)与服务器之间的信息交互的代码。

服务器端代码:

package com.udpServer;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Server1 {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(8080);
        System.out.println("服务器已经启动,等待客户端发送数据。。。");
        int count = 0;
        while(true){
            byte[] data = new byte[1024];
            DatagramPacket packet = new DatagramPacket(data, data.length);
            socket.receive(packet);
            count++;
            System.out.println("连接进来的客户端的数量为:"+count);
            new ServerThread(data,packet,socket).start();
        }

    }

}
package com.udpServer;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class ServerThread extends Thread{
    byte[] data = null;
    DatagramPacket packet = null;
    DatagramSocket socket = null;

    public ServerThread(byte[] data,DatagramPacket packet,DatagramSocket socket){
        this.data = data;
        this.packet = packet;
        this.socket = socket;
    }

    @Override
    public void run() {
        String info = new String(data,0,packet.getLength());
        System.out.println("我是服务器,客户端说:"+info);
        //服务器响应客户端信息
        InetAddress address = packet.getAddress();
        int port = packet.getPort();
        byte[] data2 = "欢迎访问服务器!".getBytes();
        DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
        try {
            socket.send(packet2);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

客户端代码:

package com.udpClient;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Client1 {
    public static void main(String[] args) throws IOException {
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8080;
        byte[] data = "用户名:admin;密码:123".getBytes();
        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
        DatagramSocket socket = new DatagramSocket();
        socket.send(packet);

        //接收服务器的相应信息
        byte[] data2 = new byte[1024];
        DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
        socket.receive(packet2);
        String relpy = new String(data2, 0, packet2.getLength());
        System.out.println("我是客户端,服务器说:"+relpy);
        socket.close();

    }

}

运行结果演示:

下面是一个文件上传(将整张图片的内容保存到mysql数据库中,因为图片很小所以直接就将图片内容直接存储到了数据库中了,如果图片很大就应该将图片上传,然后将图片的地址保存到数据库中就可以了)的代码,该代码中使用到了基于TCP的Socket的通信,数据库的基本查询和插入,基本的IO字节流的读写操作。

程序目录结构:

服务器端的Server类:

package com.test.socket;

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

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket serversocket = new ServerSocket(8888);
            System.out.println("服务器已启动,等待客户端的连接。。。");
            while(true){
                Socket socket = serversocket.accept();
                new ServerThread(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

服务器端的线程类(ServerThread类):

package com.test.socket;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import com.test.entity.FileInfo;
import com.test.entity.User;
import com.test.service.FileService;
import com.test.service.UserService;
import com.test.util.CommandTransfer;

public class ServerThread extends Thread{
    private Socket socket = null;
    private ObjectInputStream ois = null;
    private ObjectOutputStream oos = null;
    private UserService us = new UserService();//用户业务对象
    private FileService fs = new FileService();//文件业务对象

    public ServerThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            ois = new ObjectInputStream(socket.getInputStream());
            oos = new ObjectOutputStream(socket.getOutputStream());
            CommandTransfer transfer = (CommandTransfer)ois.readObject();
            transfer = execute(transfer);//执行客户端发送到服务器的指令操作
            oos.writeObject(transfer);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private CommandTransfer execute(CommandTransfer transfer) {
        String cmd = transfer.getCmd();//获取当前操作的指令
        if(cmd.equals("login")){
            User user = (User)transfer.getData();
            boolean flag = us.findLogin(user);
            transfer.setFlag(flag);
            if(flag){//判断登录是否成功
                transfer.setResult("登录成功!");
            }else{
                transfer.setResult("用户名或者密码不正确,请重新登录!");
            }
        }else if(cmd.equals("register")){
            User user = (User)transfer.getData();
            boolean flag = us.registerLogin(user);
            transfer.setFlag(flag);
            if(flag){
                transfer.setResult("注册成功!");
            }else{
                transfer.setResult("注册失败!");
            }
        }else if(cmd.equals("uploadFile")){
            FileInfo fileInfo = (FileInfo)transfer.getData();
            boolean flag = fs.uploadFile(fileInfo);
            transfer.setFlag(flag);
            if(flag){
                transfer.setResult("文件上传成功!");
            }else{
                transfer.setResult("文件上传失败!");
            }
        }
        return transfer;
    }

}

客户端代码(Client类)

package com.test.socket;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import com.test.entity.FileInfo;
import com.test.entity.User;
import com.test.util.CommandTransfer;

public class Client {
    private static Scanner input = new Scanner(System.in);
    private static Socket socket = null;

    public static void main(String[] args) {
        showMainMenu();
    }

    private static void showMainMenu() {
        System.out.println("*****欢迎使用文件上传器******");
        System.out.println("1.登录\n2.注册\n3.退出");
        System.out.println("*************************");
        System.out.println("请选择:");
        int choice = input.nextInt();
        switch (choice) {
        case 1:
            showLogin();
            break;
        case 2:
            showRegister();
            break;
        case 3:
            System.out.println("再见,感谢您对本系统的支持!");
            System.exit(0);
            break;

        default:
            System.out.println("输入有误!");
            System.exit(0);
            break;
        }

    }

    /**
     * 注册操作
     */
    private static void showRegister(){
        CommandTransfer transfer = new CommandTransfer();
        while(true){
            System.out.print("请输入用户名:");
            String username = input.next();
            System.out.print("请输入密码:");
            String password = input.next();
            System.out.print("请再次输入密码:");
            String password2 = input.next();
            if(!password.equals(password2)){
                System.out.println("两次输入的密码不一致!");
                System.out.println("**********************");
                continue;
            }
            User user = new User(username,password);
            transfer.setCmd("register");
            transfer.setData(user);

            try {
                socket = new Socket("localhost",8888);
                sendData(transfer);//将数据发送到服务器
                transfer = getData();//获取服务器返回的数据
                System.out.println(transfer.getResult());//输出显示结果
                System.out.println("*****************");
                if(transfer.isFlag()){
                    break;//如果注册成功,则不再重复执行注册操作
                }

            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        showLogin();//注册成功后显示登录
    }

    /**
     * 登录操作
     */
    private static void showLogin() {
        CommandTransfer transfer = new CommandTransfer();
        int count = 0;
        while (true) {
            count++;
            if (count > 3) {
                System.out.println("您已经连续三次登录失败,程序退出!");
                System.exit(0);
            }
            System.out.print("请输入用户名:");
            String username = input.next();
            System.out.print("请输入密码:");
            String password = input.next();
            User user = new User(username, password);
            transfer.setCmd("login");
            transfer.setData(user);

            try {
                socket = new Socket("localhost",8888);
                sendData(transfer);//将数据发送到服务器
                transfer = getData();//获取服务器返回的数据
                System.out.println(transfer.getResult());//输出显示结果
                System.out.println("************************");
                if(transfer.isFlag()){
                    break;//如果登录成功,则不再重复执行登录
                }

            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        showUploadFile();//登录成功后进行文件上传

    }

    /**
     * 文件上传操作
     */
    private static void showUploadFile() {
        CommandTransfer transfer = new CommandTransfer();
        System.out.println("请输入上传文件的绝对路径(如:E:/photo.jpg");
        String path = input.next();
        FileInfo fileInfo = null;
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        String filename = path.substring(path.lastIndexOf("/")+1);
        try {
            fis = new FileInputStream(path);
            byte[] content = new byte[fis.available()];
            bis = new BufferedInputStream(fis);
            bis.read(content);
            fileInfo = new FileInfo(filename, content);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        transfer.setCmd("uploadFile");
        transfer.setData(fileInfo);
        try {
            socket = new Socket("localhost",8888);
            sendData(transfer);
            transfer = getData();
            System.out.println(transfer.getResult());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    private static CommandTransfer getData() {
        CommandTransfer transfer = new CommandTransfer();
        try {
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            transfer = (CommandTransfer)ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return transfer;
    }

    private static void sendData(CommandTransfer transfer) {
        try {
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(transfer);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

文件储存到数据库中的操作类(FileService):

package com.test.service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.test.entity.FileInfo;
import com.test.util.DBUtil;

public class FileService {
    private Connection conn = null;
    private PreparedStatement pstmt = null;
    private DBUtil dbutil= null;

    public FileService(){
        dbutil = new DBUtil();
        this.conn = dbutil.getConnection();

    }

    public boolean uploadFile(FileInfo fileInfo){
        boolean flag = false;
        String sql = "insert into fileinfo(filename,content) values (?,?)";
        try {
            this.pstmt = this.conn.prepareStatement(sql);
            this.pstmt.setString(1,fileInfo.getFilename() );
            this.pstmt.setBytes(2, fileInfo.getContent());
            if(this.pstmt.executeUpdate()==1){
                flag = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            dbutil.DBCclose();
        }
        return flag;
    }

}

用户信息储存到数据库中的操作类(UserService):

package com.test.service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.test.entity.User;
import com.test.util.DBUtil;

public class UserService {
    private Connection conn = null;
    private PreparedStatement pstmt = null;
    private DBUtil dbutil = null;

    public UserService(){
        dbutil = new DBUtil();
        this.conn = dbutil.getConnection();
    }

    public boolean findLogin(User user){
        boolean flag = false;
        String sql = "select username from user where username = ?and password =?";
        try {
            this.pstmt = this.conn.prepareStatement(sql);
            this.pstmt.setString(1, user.getUsername());
            this.pstmt.setString(2, user.getPassword());
            ResultSet result = this.pstmt.executeQuery();
            if(result.next()){
                flag = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            dbutil.DBCclose();
        }

        return flag;
    }

    public boolean registerLogin(User user){
        boolean flag = false;
        String sql = "insert into user(username,password) values (?,?)";
        try {
            this.pstmt = this.conn.prepareStatement(sql);
            this.pstmt.setString(1, user.getUsername());
            this.pstmt.setString(2, user.getPassword());
            if(this.pstmt.executeUpdate()==1){
                flag = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            dbutil.DBCclose();
        }
        return flag;
    }

}

数据库工具类(DBUtil类):

package com.test.util;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBUtil {
    private static final String DBDRIVER = "com.mysql.jdbc.Driver";
    private static final String DBUSER = "root";
    private static final String DBPWD = "123";
    private static final String DBURL = "jdbc:mysql://localhost:3306/fileupdown";
    private Connection conn = null;

    /**
     * 构造方法中进行数据库的连接
     */
    public DBUtil() {
        try {
            Class.forName(DBDRIVER).newInstance();// 加载数据库的驱动类
            conn = DriverManager.getConnection(DBURL, DBUSER, DBPWD);// 连接数据库
            System.out.println("连接数据库成功!!!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭数据库
     */
    public void DBCclose() {
        if (this.conn != null) {
            try {
                this.conn.close();//数据库关闭操作
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 取的数据库连接对象
     */
    public Connection getConnection(){
        return this.conn;
    }

}

客户端和服务器之间传输的指令数据工具类(CommandTransfer):

package com.test.util;

import java.io.Serializable;

/**
 * 此类表示客户端和服务器之间传输的指令数据
 * 2015年8月28日 下午5:26:07
 * @author 张耀晖
 *
 */
public class CommandTransfer implements Serializable{

    private static final long serialVersionUID = 1L;
    private String cmd;//当前操作的命令
    private Object data;//发送的数据
    private boolean flag;//操作是否成功
    private String result;//返回的结果
    public String getCmd() {
        return cmd;
    }
    public void setCmd(String cmd) {
        this.cmd = cmd;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public boolean isFlag() {
        return flag;
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    public String getResult() {
        return result;
    }
    public void setResult(String result) {
        this.result = result;
    }

}

文件信息实体类(FileInfo类):

package com.test.entity;

import java.io.Serializable;

public class FileInfo implements Serializable{

    private static final long serialVersionUID = 1L;
    private int id;//文件编号
    private String filename;//文件名
    private byte[] content;//文件内容
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getFilename() {
        return filename;
    }
    public void setFilename(String filename) {
        this.filename = filename;
    }
    public byte[] getContent() {
        return content;
    }
    public void setContent(byte[] content) {
        this.content = content;
    }
    public FileInfo(String filename, byte[] content) {
        this.filename = filename;
        this.content = content;
    }

}

用户信息实体类(User类):

package com.test.entity;

import java.io.Serializable;

public class User implements Serializable{

    private static final long serialVersionUID = 1L;
    private int id;//编号
    private String username;//用户名
    private String password;//密码
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public User( String username, String password) {
        this.username = username;
        this.password = password;
    }

}

运行结果演示:

该程序代码下载地址:

点击下载代码

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 12:49:38

Java中Socket通信的知识回顾---学习笔记的相关文章

java中字符流的知识点---IO学习笔记(三)

字符流: 文本和文本文件的区别: 文本: java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码). 文件: 文件是byte byte byte-的数据序列. 文本文件: 文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结果. 字符流(Reader,Writer) 操作的是文本文件.对于mp3,二进制文件是字节文件不适合用字符流读取,因为读取出来的是char,没有意义. 字符的处理,一次处理一个字符 字符的

1.JAVA中使用JNI调用C++代码学习笔记

Java 之JNI编程1.什么是JNI? JNI:(Java Natibe Inetrface)缩写. 2.为什么要学习JNI?  Java 是跨平台的语言,但是在有些时候仍然是有需要调用本地代码 (这些代码通常是由C/C++编写的). Sun公司提供的JNI是Java平台的一个功能强大的接口.这个JNI接口提供了Java与操作系统本地代码互相调用的功能.(即java调用C++代码) 最简单的Java调用C/C++代码步骤 1.创建TestNativeCode工程,新建cn.itcast包,新建

java中的字节流的知识点---IO学习笔记(二)

IO流: 包括字节流和字符流. 在这里解释一下我对于流的理解,其实流就相当于一个用来运输字节或者字符的管道,一开始会把所有的数据存放到流中,然后我们再从流中取出数据(进行读取或者写出操作),每读或者写一次就会从管道中把读或者写的数据取出来,管道中就没有了你刚才读到或者写出的数据了.比如: FileInputStream fis = new FileInputStream(String filename); 就会把文件名为filename的文件内容全部存放到管道中去,然后我们进行fis.read(

java NIO socket 通信实例

java Nio 通信与Bio通信主要不同点: 1.Nio中的单个channel即可支持读操作也可以支持写操作,而bio中读操作要用inputstream,写操作要outputstream. 2.nio 采用byteBuffer 作为内存缓存区,向channel里写或者度操作,bio基本是用byte[] 3.nio采用 selector组件轮询读取就绪channel 服务端demo代码: package com.my.socket3; import java.io.ByteArrayOutput

java中常见的输入输出流案例学习

字节输入流: 1.FileInputStream 用途:从文件系统中的文件获得输入字节,常用于读取图像.声音等原始字节流,读取字符流可考虑使用FileReader 详细构造函数与常用方法可参考API文档,网上已经有中文版的API了,我是个E文盲,伤不起 这里介绍一个最常见的方法: read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中. ->off:b字节数组中的偏移量 小知识:数组偏移量,比如a[1,2,3,4,5]

Java中的NIO基础知识

上一篇介绍了五种NIO模型,本篇将介绍Java中的NIO类库,为学习netty做好铺垫 Java NIO 由3个核心组成,分别是Channels,Buffers,Selectors.本文主要介绍着三个部分. Channel 所有的I/O都从一个Channel开始.通道与流不同,通道是双向的,流是单向的. 即可以从通道中读取数据,也可以写数据到通道里 . 读的话,是从通道读取数据到缓冲区,写的话是从缓冲区写入数据到通道. 四种通道: FileChannel.从文件中读写数据 DatagramCha

Java中String的基础知识

Java中String的基础知识 ==与equal的区别 基本数据类型,指的是java中的八种基本数据结构(byte,short,char,int,long,float,double,boolean),一般的比较是使用的 ==,比较的是他们的值. 复合数据类型(类) ==比较的是两个对象的引用,可以理解为在内存中的地址,除非是同一个new出来的对象,他们的 ==为true,否则,都为false. equal是object中的方法.object中的实现如下,内部还是使用==实现,也就是说,如果一个

详解C#中Socket通信(一):实现连接

第一步:实现连接 客户端连接代码: private void connect2Server() { Socket clientSocket; //服务器地址 IPAddress ip = IPAddress.Parse("192.168.1.136"); //服务器节点 IPEndPoint iep = new IPEndPoint(ip, 9004); //通信实例 clientSocket = new Socket(AddressFamily.InterNetwork, Socke

java中多线程通信实例:生产者消费者模式

线程间的通信: 其实就是多个线程再操作同一个资源,但是操作的动作不同   当某个线程进入synchronized块后,共享数据的状态不一定满足该线程的需要,需要其他线程改变共享数据的状态后才能运行,而由于当时线程对共享资源时独占的,它必须解除对共享资源的锁定的状态,通知其他线程可以使用该共享资源. Java中的 wait(),notify(),notifyAll()可以实现线程间的通信. 生产者--消费者问题是典型的线程同步和通信问题 /** * 生产者和消费者问题,生产者生成出产品,消费者去购