Java Socket应用 基于TCP的通信 (多线程)

套接字通信的概念:

在应用层向传输层进行数据推行时,TCP/UDP并不是每次只为单个应用程序进程提供服务,很多时候会有很多个应用程序进程同时提出请求服务。

多个TCP连接或者多个应用程序进程可能需要通过一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序和TCP/IP协议交互提供了称为套接字(Socket)的接口。套接字是网络通信的应用程序接口。

根据网咯通信的特征,套接字主要分为两类:
1 基于TCP的流式套接字(可靠,全双工的字节流服务,需要建立连接)
2 基于UDP的数据报套接字(不可靠、不完整,不需要建立连接)

以下是基于TCP的流式套接字 网络通信

以下是 服务端 Server.java

package com.dulu.TCP;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    /**
     *基于TCP的Socket通信,实现用户登录
     *服务器端
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
         try {
             //1 创建一个服务器端的Socket 即 ServerSocket,指定绑定的端口,并监听此端口
            ServerSocket serverSocket = new ServerSocket(8888);//端口号尽量为1023之后的

            Socket socket = null;

            //定义客户端的数量
            int count = 0;

            System.out.println("***服务器即将启动,等待客户端的连接***");
             //2循环监听等待客户端的连接,调用accept()方法开始监听,等待客户端连接
            while(true){
                socket = serverSocket.accept();//处于阻塞状态,等待客户端的请求

                //创建一个新的线程
                ServletThread servletThread = new ServletThread(socket);
                //启动线程
                servletThread.start();

                count++;//统计客户端的个数
                System.out.println("客户端的数量为:" + count);
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

package com.dulu.TCP;

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 {
// 1 创建客户端Socket,指定服务器和端口
Socket socket = new Socket("localhost",8888);
 //2 获取输出流,向服务端发送信息
OutputStream os = socket.getOutputStream();//字节输入流
PrintWriter pw = new PrintWriter(os);//将输出流打包为打印流
pw.write("用户名:admin;密码:123");
pw.flush();
socket.shutdownOutput();//关闭输出流

//3 获取输入流 接受服务端的响应信息
InputStream is = socket.getInputStream();//字节输入流
InputStreamReader isr =new InputStreamReader(is);//转换为字符流

//为字符输入流添加缓冲
BufferedReader  br = new BufferedReader(isr);

String info = null;
while((info = br.readLine())!=null){
System.out.println("我是客户端,服务器说:"+ info);

}

//关闭资源
br.close();
    is.close();
isr.close();
pw.close();
os.close();
socket.close();

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

ServletThread.java

package com.dulu.TCP;

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;

/**
 * 服务器端线程处理类
 */
public class ServletThread extends Thread {

    //和本线程相关的socket
    Socket socket = null;

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

    //线程执行的操作,响应客户端的请求
    public void run(){

        InputStream is = null;
        InputStreamReader isr = null;

        BufferedReader br = null;

        OutputStream os = null;
        PrintWriter pw = null;
        try {
            // 获取输入流,并读取客户端信息
            is = socket.getInputStream();
            isr = new InputStreamReader(is);

            br = new BufferedReader(isr);

            //读取数据
            String info = null;
            while((info = br.readLine())!=null){
                System.out.println("我是服务器,客户端说:"+ info);

            }
            socket.shutdownInput();//关闭输入流

            // 获取输出流,响应客户端的请求
            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            pw.write("欢迎你!");
            pw.flush();//输出缓冲区
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            // 关闭资源
            try {
                if(pw!=null)
                    pw.close();
                if(os!=null)
                    os.close();
                if(br!=null)
                    br.close();
                if(isr!=null)
                    isr.close();
                if(is!=null)
                    is.close();
                if(socket!=null)
                    socket.close();
            } catch (IOException e) {               
                e.printStackTrace();
            }
        }

    }

}

测试结果:

首先,运行服务端程序
这里写图片描述

接下来,再运行客户端程序,(此时不可关闭服务端程序)
这里写图片描述

再控制台切换到显示服务端:
这里写图片描述

再次运行客户端程序:

以下是服务端输出结果,客户端的结果和之前的一致

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值