Java网络编程之基于TCP协议

一、单向通信

功能:客户端发送一句话到服务器:

客户端:

public class TestClient {//客户端
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.创建套接字:指定服务器的ip和端口号:
        Socket s = new Socket("192.168.199.217",8888);
        //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
        OutputStream os = s.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        //利用这个OutputStream就可以向外发送数据了,但是没有直接发送String的方法
        //所以我们又在OutputStream外面套了一个处理流:DataOutputStream
        dos.writeUTF("你好");
        //3.关闭流  +  关闭网络资源:
        dos.close();
        os.close();
        s.close();
    }
}

服务器端:

public class TestServer {//服务器
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.创建套接字: 指定服务器的端口号
        ServerSocket ss = new ServerSocket(8888);
        //2.等着客户端发来的信息:
        Socket s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
        //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
        //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
        //3.感受到的操作流:
        InputStream is = s.getInputStream();
        DataInputStream dis = new DataInputStream(is);
        //4.读取客户端发来的数据:
        String str = dis.readUTF();
        System.out.println("客户端发来的数据为:"+str);

        //5.关闭流+关闭网络资源:
        dis.close();
        is.close();
        s.close();
        ss.close();
    }
}

测试:

先开启客户端还是先开启服务器:先开服务器,再开启客户端 侧面验证:先开客户端:出错。

如图:

二、双向通信

客户端:

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

public class TestClient {//客户端
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.创建套接字:指定服务器的ip和端口号:
        Socket s = new Socket("192.168.199.217",8888);
        //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
        OutputStream os = s.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        //利用这个OutputStream就可以向外发送数据了,但是没有直接发送String的方法
        //所以我们又在OutputStream外面套了一个处理流:DataOutputStream
        dos.writeUTF("你好");
        //接收服务器端的回话--》利用输入流:
        InputStream is = s.getInputStream();
        DataInputStream dis = new DataInputStream(is);
        String str = dis.readUTF();
        System.out.println("服务器端对我说:"+str);
        //3.关闭流  +  关闭网络资源:
        dis.close();
        is.close();
        dos.close();
        os.close();
        s.close();
    }
}

服务器端:

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

public class TestServer {//服务器
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.创建套接字: 指定服务器的端口号
        ServerSocket ss = new ServerSocket(8888);
        //2.等着客户端发来的信息:
        Socket s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
        //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
        //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
        //3.感受到的操作流:
        InputStream is = s.getInputStream();
        DataInputStream dis = new DataInputStream(is);
        //4.读取客户端发来的数据:
        String str = dis.readUTF();
        System.out.println("客户端发来的数据为:"+str);
        //向客户端输出一句话:---》操作流---》输出流
        OutputStream os = s.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF("你好,我是服务器端,我接受到你的请求了");
        //5.关闭流+关闭网络资源:
        dos.close();
        os.close();
        dis.close();
        is.close();
        s.close();
        ss.close();
    }
}

注意:关闭防火墙

三、对象流传送

封装的User类:

import java.io.Serializable;

public class User implements Serializable {
    private static final long serialVersionUID = 9050691344308365540L;
    private String name;
    private String pwd;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public User(String name, String pwd) {
        this.name = name;
        this.pwd = pwd;
    }
}

客户端:

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

public class TestClient {//客户端
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException {
        //1.创建套接字:指定服务器的ip和端口号:
        Socket s = new Socket("192.168.199.217",8888);
        //录入用户的账号和密码:
        Scanner sc = new Scanner(System.in);
        System.out.println("请录入您的账号:");
        String name = sc.next();
        System.out.println("请录入您的密码:");
        String pwd = sc.next();
        //将账号和密码封装为一个User的对象:
        User user = new User(name,pwd);
        //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
        OutputStream os = s.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        oos.writeObject(user);
        //接收服务器端的回话--》利用输入流:
        InputStream is = s.getInputStream();
        DataInputStream dis = new DataInputStream(is);
        boolean b = dis.readBoolean();
        if(b){
            System.out.println("恭喜,登录成功");
        }else{
            System.out.println("对不起,登录失败");
        }
        //3.关闭流  +  关闭网络资源:
        dis.close();
        is.close();
        oos.close();
        os.close();
        s.close();
    }
}

服务器:

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

public class TestServer {//服务器
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1.创建套接字: 指定服务器的端口号
        ServerSocket ss = new ServerSocket(8888);
        //2.等着客户端发来的信息:
        Socket s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
        //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
        //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
        //3.感受到的操作流:
        InputStream is = s.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
        //4.读取客户端发来的数据:
        User user = (User)(ois.readObject());
        //对对象进行验证:
        boolean flag = false;
        if(user.getName().equals("娜娜")&&user.getPwd().equals("123123")){
            flag = true;
        }
        //向客户端输出结果:---》操作流---》输出流
        OutputStream os = s.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeBoolean(flag);
        //5.关闭流+关闭网络资源:
        dos.close();
        os.close();
        ois.close();
        is.close();
        s.close();
        ss.close();
    }
}

四、加入完整的处理异常方式

服务器端:

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

public class TestServer {//服务器
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        //1.创建套接字: 指定服务器的端口号
        ServerSocket ss = null;
        Socket s = null;
        InputStream is = null;
        ObjectInputStream ois = null;
        OutputStream os = null;
        DataOutputStream dos = null;
        try {
            ss = new ServerSocket(8888);
            //2.等着客户端发来的信息:
            s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
            //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
            //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
            //3.感受到的操作流:
            is = s.getInputStream();
            ois = new ObjectInputStream(is);
            //4.读取客户端发来的数据:
            User user = (User)(ois.readObject());
            //对对象进行验证:
            boolean flag = false;
            if(user.getName().equals("娜娜")&&user.getPwd().equals("123123")){
                flag = true;
            }
            //向客户端输出结果:---》操作流---》输出流
            os = s.getOutputStream();
            dos = new DataOutputStream(os);
            dos.writeBoolean(flag);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            //5.关闭流+关闭网络资源:
            try {
                if(dos!=null){
                    dos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os!=null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(ois!=null){
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(is!=null){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(s!=null){
                    s.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(ss!=null){
                    ss.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

客户端:

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

public class TestClient {//客户端
    //这是一个main方法,是程序的入口:
    public static void main(String[] args){
        //1.创建套接字:指定服务器的ip和端口号:
        Socket s = null;
        OutputStream os = null;
        ObjectOutputStream oos = null;
        InputStream is = null;
        DataInputStream dis = null;
        try {
            s = new Socket("192.168.199.217",8888);
            //录入用户的账号和密码:
            Scanner sc = new Scanner(System.in);
            System.out.println("请录入您的账号:");
            String name = sc.next();
            System.out.println("请录入您的密码:");
            String pwd = sc.next();
            //将账号和密码封装为一个User的对象:
            User user = new User(name,pwd);
            //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
            os = s.getOutputStream();
            oos = new ObjectOutputStream(os);
            oos.writeObject(user);
            //接收服务器端的回话--》利用输入流:
            is = s.getInputStream();
            dis = new DataInputStream(is);
            boolean b = dis.readBoolean();
            if(b){
                System.out.println("恭喜,登录成功");
            }else{
                System.out.println("对不起,登录失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            //3.关闭流  +  关闭网络资源:
            try {
                if(dis!=null){
                    dis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(is!=null){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(oos!=null){
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os!=null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(s!=null){
                    s.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

五、多线程接收用户请求

问题:

  • 服务器针对一个请求服务,之后服务器就关闭了(程序自然结束了)

需要解决:

  • 服务器必须一直在监听 ,一直开着,等待客户端的请求
  • 在当前代码中,客户端不用动了

更改服务器代码:

服务器线程:

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

public class ServerThread extends Thread {//线程:专门处理客户端的请求
    InputStream is = null;
    ObjectInputStream ois = null;
    OutputStream os = null;
    DataOutputStream dos = null;
    Socket s = null;
    public ServerThread(Socket s){
        this.s = s;
    }
    @Override
    public void run() {
        try{
            //2.等着客户端发来的信息:
            is = s.getInputStream();
            ois = new ObjectInputStream(is);
            //4.读取客户端发来的数据:
            User user = (User)(ois.readObject());
            //对对象进行验证:
            boolean flag = false;
            if(user.getName().equals("娜娜")&&user.getPwd().equals("123123")){
                flag = true;
            }
            //向客户端输出结果:---》操作流---》输出流
            os = s.getOutputStream();
            dos = new DataOutputStream(os);
            dos.writeBoolean(flag);
        }catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if(dos!=null){
                    dos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os!=null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(ois!=null){
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(is!=null){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

服务器端:

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

public class TestServer {//服务器
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        System.out.println("服务器启动了");
        //1.创建套接字: 指定服务器的端口号
        ServerSocket ss = null;
        Socket s = null;
        int count = 0;//定义一个计数器,用来计数  客户端的请求
        try {
            ss = new ServerSocket(8888);
            while(true){//加入死循环,服务器一直监听客户端是否发送数据
                s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
                //每次过来的客户端的请求 靠 线程处理:
                new ServerThread(s).start();
                count++;
                //输入请求的客户端的信息:
                System.out.println("当前是第"+count+"个用户访问我们的服务器,对应的用户是:"+s.getInetAddress());
            }
        } catch (IOException  e) {
            e.printStackTrace();
        }
    }
}

到此这篇关于Java网络编程之基于TCP协议的文章就介绍到这了,更多相关Java基于TCP的网络编程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java实现基于TCP协议网络socket编程(C/S通信)

    一.前言:TCP原理简介 首先,保证文章完整性,TCP的理论原理还是需要简介一下,略显枯燥๑乛◡乛๑. TCP(传输控制协议,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议.TCP旨在适应支持多网络应用的分层协议层次结构.也就是说,TCP是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议. 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务. 以上TCP的特点,也正是与UD

  • 老生常谈Java网络编程TCP通信(必看篇)

    Socket简介: Socket称为"套接字",描述IP地址和端口.在Internet上的主机一般运行多个服务软件,同时提供几种服务,每种服务都打开一个Socket,并绑定在一个端口上,不同的端口对应于不同的服务.Socket和ServerSocket类位于java.net包中.ServerSocket用于服务端,Socket是建立网络连接时使用的.连接成功时,应用程序两端都会产生一个Socket实例,通过操作这个实例完成所需会话. Socket常用方法: -int getLocalP

  • Java网络编程之TCP通信完整代码示例

    一.概述 Socket类是Java执行客户端TCP操作的基础类,这个类本身使用代码通过主机操作系统的本地TCP栈进行通信.Socket类的方法会建立和销毁连接,设置各种Socket选项. ServerSocket类是Java执行服务器端操作的基础类,该类运行于服务器,监听入站TCP连接,每个socket服务器监听服务器的某个端口,当远程主机的客户端尝试连接此端口时,服务器就被唤醒,并返回一个表示两台主机之间socket的正常Socket对象. 二.什么是TCP? TCP是一种面向连接的.可靠的.

  • Java基于TCP协议socket网络编程的文件传送的实现

    先了解一下socket基本概念 socket也叫套接字: 是指在网路中不同主机上的应用进程之间,进行双向通信的端点的抽象. 简单理解就是: 两个主机之间要通信,就需要知道彼此的ip,端口号等信息,而一台主机这些信息的集合: 就可以理解为一个端点,即为套接字 双方通过套接字作为一种坐标,建立信息通道,形成连接(两点连接一条直线) 简单理解了套接字的概念后,来看看如何通过java socket编程来实现 两台主机文件的接收与发送: 代码如下: 发送方: import java.io.*; impor

  • Java网络编程之TCP程序设计

    本文实例为大家分享了Java网络编程TCP程序设计的具体代码,供大家参考,具体内容如下 [1] TCP编程的主要步骤 客户端(client): 1.创建Socket对象,构造方法的形参列表中需要InetAddress类对象和int型值,用来指明对方的IP地址和端口号. 2.通过Socket对象的getOutputStream()方法返回OutputStream抽象类子类的一个对象,用来发送输出流. 3.通过输出流的write方法输出具体的信息. 4.关闭相应的流和Socket对象. 服务端(se

  • java 网络编程之TCP通信和简单的文件上传功能实例

    TCP通信需要明确的几点: tcp通信是面向连接的,需要先启动服务端,再启动客户端. 客户端和服务端都要创建套接字对象,客户端需要指定服务端套接字(ip+port),而服务端必须指定服务端口. Socket client_socket = new Socket("192.168.100.17",8888); //客户端套接字(Socket类的套接字为已连接套接字) ServerSocket listen_socket = new ServerSocket(8888); //服务端套接字

  • Java 基于TCP Socket 实现文件上传

    文件上传过程一个单向Socket通信过程.客户端通过文件输入流读取文件,然后从Socket获取输出流写入数据.服务端从Socket中获得输入流,然后写入文件输出流,写入数据完成则上传完成. 服务端UploadServer: public class UplaodServer { public static void main(String []args){ try( // 创建一个ServerSocket监听8080端口的请求 // ServerSocket 实现了 AutoCloseable接

  • Java 网络编程之 TCP 实现简单的聊天系统

    客户端 1.连接服务器 Socket 2.发送消息 package lesson02; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; /** * 客户端 */ public class TcpClientDemo1 { public static void main(String[] args) { Socket socke

  • Java多线程实现TCP网络Socket编程(C/S通信)

    开篇必知必会 在前一篇<基于TCP协议网络socket编程(java实现C/S通信)>,实际存在一个问题,如果服务器端在建立连接后发送多条信息给客户端,客户端是无法全部接收的,原因在于客户端为单线程,只接受了第一条信息,剩余信息阻塞等待下一次发送.所以,这造成了客户端无法处理消息队列,每次只接收并输出一条服务器信息,出现信息不同步问题. 本篇将解决这个问题,详细记录实现java多线程通信,目标是使客户端可以一次接收服务器发送的多条信息,避免阻塞.方法是将客户端接收信息功能独立为一个线程来完成,

  • Java网络编程之基于TCP协议

    一.单向通信 功能:客户端发送一句话到服务器: 客户端: public class TestClient {//客户端 //这是一个main方法,是程序的入口: public static void main(String[] args) throws IOException { //1.创建套接字:指定服务器的ip和端口号: Socket s = new Socket("192.168.199.217",8888); //2.对于程序员来说,向外发送数据 感受 -->利用输出流

  • Java编程实现基于TCP协议的Socket聊天室示例

    本文实例讲述了Java编程实现基于TCP协议的Socket聊天室.分享给大家供大家参考,具体如下: 这里使用Socket套接字进行编程,完成的是基于TCP可靠服务实现服务器与客户端的双通信. Server服务器端: package com.han; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.Win

  • Java基于Tcp协议的socket编程实例

    本文实例讲述了Java基于Tcp协议的socket编程方法,分享给大家供大家参考.具体分析如下: 以下是一对一的通信编程实现,后续会继续学习一个服务器监听多个客户端的实现. 这里用到的主要步骤如下: 第一步:以特定端口(如4800)新建socket对象 第二步:以系统输入设备构造BufferedReader对象,该对象用于接收系统键盘输入的字符 第三步:以socket对象 得到输出流来构造PrintWriter 第四步:以socket对象得到输入流来构造相应的BufferedReader对象,该

  • java编程实现基于UDP协议传输数据的方法

    本文实例讲述了java编程实现基于UDP协议传输数据的方法.分享给大家供大家参考,具体如下: UDP协议(User Datagram Protocol,用户数据报协议)不同于TCP协议,它是不可能靠的,但是它比TCP协议具有更快的传输速度,UDP发送的数据单元称为数据报,当网络传输UDP传输UDP数据报是无法保证数据能够到达目的地,也无法保证按发送的顺序到达目的地,也就是说先发送了"hello",再发送了"world",但接收方可能会先收到"world&q

  • JAVA实现基于Tcp协议的简单Socket通信实例

    好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西.  1.首先先来看下基于TCP协议Socket服务端和客户端的通信模型: Socket通信步骤:(简单分为4步) 1.建立服务端ServerSocket和客户端Socket 2.打开连接到Socket的输出输入流 3.按照协议进行读写操作 4.关闭相对应的资源 2.相关联的API: 1.首先先来看下

  • Java基于TCP协议的Socket通信

    目录 简介 TCP简介 JAVA Socket简介 SocketImpl介绍 TCP 编程 构造ServerSocket 1.1 绑定端口 1.2 设定客户连接请求队列的长度 1.3 设定绑定的IP 地址 1.4 默认构造方法的作用 多线程示例 简介 TCP简介 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户

  • python 基于TCP协议的套接字编程详解

    基于TCP协议的套接字编程 实现电话沟通为例,这里传递的是字符,可以自己尝试去发送一个文件 # 服务端 import socket # 1. 符合TCP协议的手机 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # TCP # 2. 绑定手机号 一个服务器,我们自己的电脑作为服务器的话,用自己的IP地址 server.bind(('127.0.0.1',8000)) # 127.0.0.1 代表本地 # server.bind(

随机推荐