美文网首页TCP
Java网络编程之TCP网络通信

Java网络编程之TCP网络通信

作者: 征程_Journey | 来源:发表于2017-05-21 11:28 被阅读88次

    1      网络编程----TCPNo24

    public class Server {

    public static void main(String[] args){

    try {

    ServerSocket ss =new ServerSocket(8888);//在8888端口上建立ServerSocket

    Socket s =ss.accept();//监听客户端的连接请求,一旦连接请求到达,建立连接,会返回一个服务器端的Socket

    InputStream is =s.getInputStream();//获取这个Socket的输入流,用于读取客户端传来的信息

    int b = is.read();//读一个字节

    System.out.println(b);//打印

    s.close();//关闭和客户端的连接

    ss.close();//关闭ServerSocket,之后不再去监听端的连接请求

    } catch (IOException e) {

    // TODOAuto-generated catch block

    e.printStackTrace();

    }

    }

    }

    public class Client {

    public static void main(String[] args){

    try {

    Socket s = newSocket("127.0.0.1",8881);//向本机8888端口发送连接请求

    OutputStream os =s.getOutputStream();//获取客户端Socket的输出流

    os.write(100);//写一个字节100

    s.close();//关闭套接字

    } catch (IOException e) {

    // TODOAuto-generated catch block

    e.printStackTrace();

    }

    }

    }

    网络

    Protocol协议就是一种格式、约定,网络两端的主机可以根据这个约定来进行信息的交互和传输

    网络四层协议体系架构TCP/IP

    1、应用层  http、ftp

    2、传输层  TCP、UDP

    3、网络互联层  IP

    4、主机到网络层

    1.1    基本网络知识

    1.1.1  Ip地址

    InetAddress类的使用:

    getByName(Stringhost):根据主机名获取IP对象

    getHostAddress():获取主机地址

    getHostName():获取主机名

    getAllByName(Stringhost):获取主机名获取所有的IP对象

    getLocalHost():获取本地主机对应的IP地址(127.0.0.1)

    示例代码

    //在Java中,使用InetAddress类描叙网络地址

    InetAddress inetAddr = null;

    //创建InetAddress对象

    //在互联网上访问服务器有两种形式:1、ip地址   2、主机名(例如:http://www.baidu.com)

    //               inetAddr =InetAddress.getByName("www.baidu.com");

    //               inetAddr =InetAddress.getByName("192.168.35.1");

    //               inetAddr =InetAddress.getByName("192.168.81.144");

    //               inetAddr = InetAddress.getByName("localhost");

    //获取本机ip地址

    inetAddr =InetAddress.getLocalHost();

    //ip地址

    String address =inetAddr.getHostAddress();

    //主机名

    String host =inetAddr.getHostName();

    System.out.println(address+":"+host);

    InetAddress[] inetAddresses=InetAddress.getAllByName("www.baidu.com");

    for (InetAddress inet :inetAddresses) {

    System.out.println(inet.getHostAddress());

    }

    1.1.2  网络编程三要素

    IP地址:网络中每台主机都必须有一个唯一的IP地址(网络中设备的标识)

    端口:用于标识进程的逻辑地址,每个进程都有各自不同的标识, 有效端口0~65535,其中0-1024系统使用或保留端口

    传输协议UDP---《将数据、源地址和目的地址封装在数据报包中;每个数据报的大小被限制在64K以内;不需要建立连接;是不可靠协议,速度快》

    TCP----《建立连接,形成传输数据的通道;在连接中进行大数据传输;通过三次握手完成连接;必须建立连接;是可靠协议,效率较低》

    通过三次握手完成连接:

    【1. 客户端向服务器发送包含初始序列值的数据段,开启通信会话

    2.      服务器发送包含确认值的数据段,其值等于收到的序列值加1,并加上其自身的同步序列值

    3.      发送带确认值的客户端响应,其值等于接受的序列值加1.这便完成了整个建立连接的过程】

    1.1.3  Socket(套接字)

    1、Socket是为了网络服务而提供的一种机制;

    2、套接字是两台机器间通信的端点;

    3、网络通信其实就是Socket间的通信(所以网络编程又称为Socket编程);

    4、Socket之间通过IO流来进行数据的传输(TCP);

    5、Socket = IP地址 + 端口

    TCP  Transmit Control Protocol传输控制协议

    可以将IP报文进行包装、组织,有序可靠地传输到网络另一端

    是基于连接的,两个主机在进行通信前必须先建立连接(三次握手)

    (UDPUser Datagram protocol用户数据报协议,不需要连接,信息传输会发生丢失)

    协议都是跨语言、跨平台的

    1.2    Java实现Tcp通信

    如何用Java来进行TCP通信:

    ServerSocket服务器套接字,用来监听客户端发送来的连接请求,一旦有客户端请求连接,就可以生成一个连接,并获取服务端这头的Socket

    构造方法:ServerSocket(int port)在端口port上建立服务端套接字

    Socketaccept()监听客户端过来的连接请求,是一个阻塞方法,连接请求过来了,它就会返回建立的连接的服务端这头的套接字,这个套接字可以用来向客户端写或者从客户端读信息

    Socket套接字,就是网络上两台主机之间建立的连接的两个端点,可以通过它写信息,也可以读信息(套接字可以用于两台连接的主机之间进行通信,读写信息。)

    1.2.1  服务端

    一:服务端

    getOutputStream()获取套接字输出流

    write系列方法,使用和文件IO中差不多

    getInputStream()获取套接字输入流

    read系列方法

    1.3    客户端

    二:客户端

    构造方法:Socket(String address,int port)参数为服务端的地址以及端口号,这样构建时就能发送一个连接请求到服务端,接下来这个创建出来的Socket对象就能用来和服务端通信

    getOutputStream()获取套接字输出流

    write系列方法,使用和文件IO中差不多

    getInputStream()获取套接字输入流

    read系列方法

    getPort()获取端口号

    getInetAddress()获取英特网地址对象(可以调用这个对象的getHostAddress()获取地址字符串)

    另有一个4参构造方法Socket(String address,int port,InetAddress addr,int p)可以用第四个参数指定客户端的端口(2参构造方法的客户端端口随机分配)

    1.4    实现及理论

    Socket类:此类实现客户端套接字

    ServerSocket:《此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

    PS:在创建Socket对象时,底层会自动创建一个客户端与服务端之间的通道,这个通道就是Socket流(网络IO流),Socket流既包含输入流,又包含输出流。》

    使用步骤:

    客户端:【《

    1、 创建套接字对象(需要绑定指定的服务器ip地址和端口)

    2、 通过IO流和服务端传输数据

    3、 关闭Socket,释放资源》

    服务端:【《

    1、 创建服务端套接字对象(需要绑定端口,以便客户端连接)

    2、 等待接收来自客户端的连接请求

    3、 通过IO流与客户端传输数据

    4、 关闭资源》

    代码:

    Client.java客户端

    publicclassClient {

    publicstaticvoidmain(String[]args)throwsUnknownHostException, IOException {

    //tcp的客户端

    System.out.println("tcp客户端开启...");

    /*

    *创建Socket对象,当执行这行代码的时候底层会自动和服务端建立连接(三次握手)

    *如果连接建立不成功,就会抛出异常

    */

    //Socket socket = newSocket("127.0.0.1", 9999);

    Socketsocket=newSocket("192.168.81.143", 9999);

    //获取IO流对象,通过IO流对象可以实现与服务端的数据传输

    // socket.getInputStream();

    OutputStreamos=socket.getOutputStream();

    os.write("来自tcp客户端的数据".getBytes());

    //释放资源,断开与服务端的连接

    socket.close();

    System.out.println("tcp客户端关闭...");

    }

    }

    服务端:Server.java

    publicclass Server {

    public static void main(String[] args)throws IOException {

    // tcp的服务端

    System.out.println("tcp服务端开启...");

    // 创建服务端的套接字对象,用于响应来自客户端的连接请求

    ServerSocket serverSocket =new ServerSocket(9999);

    // 等待接收来自客户端的连接请求,连接成功后会返回与客户端对应的Socket对象

    Socket socket =serverSocket.accept(); // 阻塞式方法

    // 获取客户端的ip地址

    String ip =socket.getInetAddress().getHostAddress();

    System.out.println("与" + ip + "建立连接");

    InputStream is =socket.getInputStream();

    // socket.getOutputStream();

    byte[] buf = new byte[1024];

    int length = is.read(buf);

    System.out.println(ip +":" + new String(buf, 0, length));

    // socket.close();

    // 释放资源,关闭服务端的套接字,会断开所有的客户端连接

    serverSocket.close();

    System.out.println("tcp服务端关闭");

    }

    }

    1.5    不间断发送消息到服务器

    publicclass Client {

    public static void main(String[] args)throws UnknownHostException,

    IOException {

    // tcp的客户端

    System.out.println("tcp客户端开启...");

    Socket socket = newSocket("192.168.81.143", 9999);

    Scanner scanner = newScanner(System.in);

    /*BufferedReader br = newBufferedReader(new InputStreamReader(

    socket.getInputStream()));*/

    BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(

    socket.getOutputStream()));

    for(;;){

    String line =scanner.nextLine();

    bw.write(line);

    bw.newLine();

    bw.flush();

    }

    //               socket.close();

    //               System.out.println("tcp客户端关闭...");

    }

    }

    publicclass Server {

    public static void main(String[] args)throws IOException {

    // TODO Auto-generated methodstub

    // tcp服务端

    System.out.println("TCP服务端开启.....");

    ServerSocket serverSocket =new ServerSocket(9999);

    Socket socket =serverSocket.accept(); // 阻塞式方法

    String ip =socket.getInetAddress().getHostAddress();

    System.out.println("与" + ip + "建立连接");

    BufferedReader br = newBufferedReader(new InputStreamReader(

    socket.getInputStream()));

    String line = null;

    while((line =br.readLine())!=null){

    System.out.println(ip+"发送来:"+line);

    }

    serverSocket.close();

    System.out.println("TCP服务端关闭.....");

    }

    }

    1.6    TCP上传文件到服务器

    publicclass Client {

    // TCP的客户端

    public static void main(String[] args)throws UnknownHostException,

    IOException {

    // TODO Auto-generated methodstub

    System.out.println("TCP客户端开启.......");

    Socket socket = newSocket("192.168.81.143", 9999);

    // 将指定的文件上传到服务器

    // 一边读取文件数据,一边向服务器端写出数据

    BufferedInputStream bis = newBufferedInputStream(new FileInputStream(

    "g:\\extras下文件.rar"));

    BufferedOutputStream bos =new BufferedOutputStream(socket.getOutputStream());

    int b=0;

    while((b=bis.read())!=-1){

    bos.write(b);

    }

    bos.close();

    bis.close();

    socket.close();

    System.out.println("TCP客户端关闭.......");

    }

    }

    publicclass Server {

    public static void main(String[] args)throws IOException {

    // TODO Auto-generated methodstub

    System.out.println("tcp服务端开启....");

    ServerSocket serverSocket =new ServerSocket(9999);

    Socket socket =serverSocket.accept();

    String clientName =socket.getInetAddress().getHostName();

    BufferedInputStream bis = newBufferedInputStream(

    socket.getInputStream());

    BufferedOutputStream bos =new BufferedOutputStream(

    newFileOutputStream("g:\\" + clientName + ".rar"));

    int b = 0;

    while((b =bis.read()) !=-1){

    bos.write(b);

    }

    bos.close();

    bis.close();

    System.out.println("tcp服务端关闭...");

    }

    }

    1.7    多用户连接与数据发送

    publicclass Client {

    public static void main(String[] args)throws UnknownHostException,

    IOException {

    // TODO Auto-generated methodstub

    System.out.println("客户端开启./...");

    Socket socket = newSocket("192.168.81.144", 6001);

    System.out.println("成功与服务器建立连接....");

    // 将键盘录入的数据传输到服务器

    BufferedReader br = newBufferedReader(new InputStreamReader(System.in));

    BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(

    socket.getOutputStream()));

    //读一行写一行

    String line = null;   //接收从键盘录入的数据

    while((line=br.readLine())!=null){

    bw.write(line);

    bw.newLine();

    bw.flush();

    }

    bw.close();

    br.close();

    socket.close();

    System.out.println("客户端关闭.....");

    }

    }

    //客户端响应线程

    publicclass ClientEchoThread extends Thread {

    //客户端对应的Socket对象(每个客户端都有自己所对应的Socket对象)

    private Socket socket;

    private String ip;

    public ClientEchoThread(Socket socket){

    this.socket = socket;

    ip =socket.getInetAddress().getHostAddress();

    }

    //在线程中执行客户端的响应

    @Override

    public void run() {

    System.out.println("建立与"+ip+"的连接");

    BufferedReader br =null;

    try {

    br =newBufferedReader(new InputStreamReader(socket.getInputStream()));

    //读取来自客户端的数据

    String line = null;

    while((line =br.readLine())!= null){

    System.out.println(ip+":"+line);

    }

    } catch (IOException e) {

    // TODOAuto-generated catch block

    e.printStackTrace();

    }finally{

    if(br != null){

    try {

    br.close();

    br= null;

    } catch(IOException e) {

    //TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    if(socket != null){

    try {

    socket.close();

    socket= null;

    } catch(IOException e) {

    //TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

    }

    }

    /**

    *开启几个线程?

    *     有几个客户端就有几个线程

    *什么时候开线程?

    *     一旦有了新的客户端,就需要开启一个新的线程

    *线程中应该包含哪些代码?

    *     响应客户端的请求

    */

    publicclass Server {

    public static void main(String[] args)throws IOException {

    // TODO Auto-generated methodstub

    System.out.println("服务端开启....");

    ServerSocket serverSocket = new ServerSocket(6001);

    //接收来自客户端的连接请求

    //阻塞式方法,一旦有新的客户端连接,就会返回一个客户端对应的Socket对象

    //作为客户端,应该不停地去接受客户端的请求

    while(true){

    Socket socket =serverSocket.accept();

    newClientEchoThread(socket).start();

    }

    //        serverSocket.close();

    //        System.out.println("服务端关闭....");

    }

    }

    相关文章

      网友评论

        本文标题: Java网络编程之TCP网络通信

        本文链接:https://www.haomeiwen.com/subject/wlbmxxtx.html