使用socket实现网络TCP连接(多线程)

套接字Socket

  • 我们开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层如何使用传输层的服务呢?在应用层和传输层之间,则是使用套接字来进行分离。
  • 套接字就像传输层为应用层开的一个小口,应用程序通过这个小口向远程发送数据,或接收远程发来数据;而这个小口以内,也就是数据进入这个口之后,或者数据从这个口出来之前,是不知道也不需要知道的,也不会关心它如何传输,这属于网络其它层次的工作。
  • Socket实际是传输层供给应用层的编程接口。传输层则在网络层的基础上提供进程到进程问的逻辑通道,而应用层的进程则利用传输层向另一台主机的某一进程通信。Socket就是应用层与传输层之间的桥梁
  • 使用Socket编程可以开发客户机和服务器应用程序,可以在本地网络上进行通信,也可通过Internet在全球范围内通信。

功能:实现类似QQ、微信、邮箱、商城的网络登录功能,可以多个用户同时登录。为了便于理解,进行功能分解和迭代,分为一次单向通信、一次双向通信、传输对象、引入多线程来实现。

1.创建服务器端

由于服务器可以同时处理来自不同终端的信号,这里用到了多线程

4.创建一个线程类使得服务器可以同时接受来自不同端的用户的登录信息

3.还需要有用户类

2.创建用户端

1.服务器端代码实现

package login4;

import entity.User;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class LoginServer {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建一个ServerSocket
        ServerSocket serverSocket = new ServerSocket(8800);
        //使用SetverSocket在指定的端口监听
        int i = 1;
        while (true) {
            Socket socket = serverSocket.accept();
            //为每个登录请求创建一个线程处理
            new Loginthread(socket).start();
            //统计客户端的IP地址和总的请求次数
           InetAddress ia= socket.getInetAddress();
            System.out.println("这是第" + (i++) + "个请求,对方的ip地址是:" + ia.getHostAddress());
        }

        //serverSocket.close();

    }
}

2.线程类代码实现

package login4;

import entity.User;

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

public class Loginthread extends Thread {
    private Socket socket;

    public Loginthread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {

        //接受客户端的请求数据并输出
        InputStream is = null;
        ObjectInputStream ois =null;
        DataOutputStream dos = null;

        try {
            is = socket.getInputStream();
             ois = new ObjectInputStream(is);
            User user = (User) ois.readObject();
            System.out.println("来自客户端的请求:" + user);
            //给客户端响应
            OutputStream os = socket.getOutputStream();
           dos = new DataOutputStream(os);

            if (user.getPassword().length() >= 6) //实际应该到数据库表里查询
            {
                dos.writeUTF("登录成功,欢迎你");
            } else {
                dos.writeUTF("用户名或者密码错误!");
            }


        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            try {
                if (ois != null) {
                    ois.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (dos != null) {
                    dos.close();

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

    }
}

3.用户端代码实现

package login4;

import entity.User;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class LoginClient {
    public static void main(String[] args) throws IOException {
        //创建一个Socket,指明服务器端ip和监听窗口
        Socket socket = new Socket(InetAddress.getLocalHost(), 8800);
        Scanner input = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String userid = input.next();
        System.out.println("请输入密码:");
        String password = input.next();
        User user = new User(userid, password);
        //发送数据给服务器端
        OutputStream os = socket.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        oos.writeObject(user);

        //接受服务器资源并响应
        InputStream is = socket.getInputStream();
        DataInputStream dis = new DataInputStream(is);
        String result = dis.readUTF();
        System.out.println("来自服务器端的响应:" + result);


        //关闭资源
        dis.close();
        oos.close();
        os.close();
        socket.close();

    }
}

4.user类代码

package entity;

import java.io.Serializable;

public class User implements Serializable {

    private static final long serialVersionUID = 3748321221707475647L;
    private String userId;
    private String password;

    public User() {
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

    public User(String userId, String password) {
        this.userId = userId;
        this.password = password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId='" + userId + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

你可能感兴趣的:(java,网络,tcp/ip,网络协议)