• java Socket编程


    Java中的Socket编程:

    Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一。如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的。本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序。

    TCP和UDP通信

    关于socket编程我们有两种通信协议可以进行选择。一种是数据报通信,另一种就是流通信。

    数据报通信

    数据报通信协议,就是我们常说的UDP(User Data Protocol 用户数据报协议)。UDP是一种无连接的协议,这就意味着我们每次发送数据报时,需要同时发送本机的socket描述符和接收端的socket描述符。因 此,我们在每次通信时都需要发送额外的数据。

    流通信

    流通信协议,也叫做TCP(Transfer Control Protocol,传输控制协议)。和UDP不同,TCP是一种基于连接的协议。在使用流通信之前,我们必须在通信的一对儿socket之间建立连接。其中一个socket作为服务器进行监听连接请求。另一个则作为客户端进行连接请求。一旦两个socket建立好了连接,他们可以单向或双向进行数据传输。

    读到这里,我们多少有这样的疑问,我们进行socket编程使用UDP还是TCP呢。选择基于何种协议的socket编程取决于你的具体的客户端-服务器端程序的应用场景。下面我们简单分析一下TCP和UDP协议的区别,或许可以帮助你更好地选择使用哪种。

    在UDP中,每次发送数据报时,需要附带上本机的socket描述符和接收端的socket描述符。而由于TCP是基于连接的协议,在通信的socket对之间需要在通信之前建立连接,因此会有建立连接这一耗时存在于TCP协议的socket编程。

    在UDP中,数据报数据在大小上有64KB的限制。而TCP中也不存在这样的限制。一旦TCP通信的socket对建立了连接,他们之间的通信就类似IO流,所有的数据会按照接受时的顺序读取。

    UDP是一种不可靠的协议,发送的数据报不一定会按照其发送顺序被接收端的socket接受。然后TCP是一种可靠的协议。接收端收到的包的顺序和包在发送端的顺序是一致的。

    简而言之,TCP适合于诸如远程登录(rlogin,telnet)和文件传输(FTP)这类的网络服务。因为这些需要传输的数据的大小不确定。而 UDP相比TCP更加简单轻量一些。UDP用来实现实时性较高或者丢包不重要的一些服务。在局域网中UDP的丢包率都相对比较低。

    客户端编写:

    首先要新建一个socket:其中127.0.0.1是你要连接的机器,4000是机器进行通信的端口好

    1 Socket socket = new Socket("127.0.0.1", 4000);

     然后需要从终端中不停的监听读取数据,然后再写出来,客户端完整程序:

     1 package org.net;
     2 
     3 import java.net.*;
     4 import java.io.*;
     5 public class MainClient
     6 {
     7     public static void main(String[] args) throws Exception
     8     {
     9         Socket socket = new Socket("127.0.0.1", 4000);
    10         new ClientInputThread(socket).start();
    11         new ClientOutputThread(socket).start();
    12     }
    13 }
    14 
    15 class ClientOutputThread extends Thread
    16 {
    17     private Socket socket;
    18     public ClientOutputThread(Socket socket)
    19     {
    20         super();
    21         this.socket = socket;
    22     }
    23 
    24     public void run()
    25     {
    26         try
    27         {
    28             OutputStream os = socket.getOutputStream();
    29             while (true)
    30             {
    31                 BufferedReader reader = new BufferedReader(
    32                 new InputStreamReader(System.in));
    33                 String line = reader.readLine();
    34                 os.write(line.getBytes());
    35             }
    36         }
    37         catch (IOException e)
    38         {
    39             e.printStackTrace();
    40         }
    41     }
    42 }
    43 
    44  class ClientInputThread extends Thread
    45 {
    46     private Socket socket;
    47     public ClientInputThread(Socket socket)
    48     {
    49         super();
    50         this.socket = socket;
    51     }
    52 
    53     public void run()
    54     {
    55         try
    56         { 
    57             InputStream is = socket.getInputStream();
    58             while (true)
    59             {
    60                 byte[] buffer = new byte[1024];
    61                 int length = is.read(buffer);
    62                 String str = new String(buffer, 0, length);
    63                 System.out.println(str);
    64             }
    65         }
    66         catch (IOException e)
    67         {
    68             e.printStackTrace();
    69         }
    70     }
    71 
    72 }

    服务器编写:

    首先也要先建立一个服务端的ServerSocket,并指定和客户端一样的端口号,然后让服务器一直处于监听状态,等待连接 

    1     ServerSocket serverSocket = new ServerSocket(4000);
    2         while (true)
    3         {
    4             // 一直处于监听状态,这样可以处理多个用户
    5             Socket socket = serverSocket.accept();
    6         }

     然后服务器端也要等待输入输出流,服务器端完整代码:

     1 package org.net;
     2 
     3 import java.io.*;
     4 import java.net.*;
     5 public class MainServer
     6 {
     7     public static void main(String[] args) throws Exception
     8     {
     9         ServerSocket serverSocket = new ServerSocket(4000);
    10         while (true)
    11         {
    12             // 一直处于监听状态,这样可以处理多个用户
    13             Socket socket = serverSocket.accept();
    14 
    15             // 启动读写线程
    16             new ServerInputThread(socket).start();
    17             new ServerOutputThread(socket).start();
    18         }
    19     }
    20 }
    21 
    22 
    23 class ServerInputThread extends Thread
    24 {
    25     private Socket socket;
    26 
    27     public ServerInputThread(Socket socket)
    28     {
    29         super();
    30         this.socket = socket;
    31     }
    32 
    33     public void run()
    34     {
    35         try
    36         {
    37             // 获得输入流
    38             InputStream is = socket.getInputStream();
    39             while (true)
    40             {
    41                 byte[] buffer = new byte[1024];
    42                 int length = is.read(buffer);
    43                 String str = new String(buffer, 0, length);
    44                 System.out.println(str);
    45             }
    46         }
    47         catch (IOException e)
    48         {
    49             e.printStackTrace();
    50         }
    51     }
    52 }
    53 
    54  class ServerOutputThread extends Thread
    55 {
    56     private Socket socket;
    57     public ServerOutputThread(Socket socket)
    58     {
    59         super();
    60         this.socket = socket;
    61     }
    62     public void run()
    63     {
    64         try
    65         {
    66             OutputStream os = socket.getOutputStream();
    67             while (true)
    68             {
    69                 BufferedReader reader = new BufferedReader(
    70                         new InputStreamReader(System.in));
    71                 String line = reader.readLine();
    72                 os.write(line.getBytes());
    73             }
    74         }
    75         catch (IOException e)
    76         {
    77             e.printStackTrace();
    78         }
    79     }
    80 }

    java下面进行socket编程要比其他语言(比如c)要简单,java.net包下面有很多的类可以供我们进行调用,注意平时多查API文档

     

  • 相关阅读:
    【Aizu
    【Aizu
    【OpenJ_Bailian
    leetcode-225-Implement Stack using Queues
    leetcode-219-Contains Duplicate II(使用set来判断长度为k+1的闭区间中有没有重复元素)
    leetcode-217-Contains Duplicate(使用排序来判断整个数组有没有重复元素)
    leetcode-840-Magic Squares In Grid
    leetcode-198-House Robber(动态规划)
    leetcode-191-Number of 1 Bits
    leetcode-189-Rotate Array
  • 原文地址:https://www.cnblogs.com/snail-lb/p/5468054.html
Copyright © 2020-2023  润新知