文章目录

  • InetAddress类
  • URL类
  • URLConnection类
    • 使用URLConnection发送post请求
  • Socket类
  • DatagramSocket
  • MulticastSocket实现广播

(注:有些图片被吞了看不了也没事,因为是运行结果截图,不影响学习)

InetAddress类

InetAddress没有公有构造方法,不能通过new创建对象

    /*** Constructor for the Socket.accept() method.* This creates an empty InetAddress, which is filled in by* the accept() method.  This InetAddress, however, is not* put in the address cache, since it is not created by name.*/InetAddress() {holder = new InetAddressHolder();}

使用InetAddress获取本地主机名和ip地址

    public static void main(String[] args) throws UnknownHostException {InetAddress inetAddress = InetAddress.getLocalHost();System.out.println("主机名: " + inetAddress.getHostName());System.out.println(inetAddress.toString());InetAddress inetAddress2 = InetAddress.getByName("220.181.38.150");System.out.println("主机名2: " + inetAddress2.getCanonicalHostName());System.out.println(inetAddress2.toString());}

URL类

解析url字符串,这个url可能访问无效,只要长得像一个url就行

    public static void main(String[] args) {try {URL url = new URL("http://www.tsinghua.edu.cn/chn/index.htm");System.out.println("the Protocol: " + url.getProtocol());System.out.println("the hostname: " + url.getHost());System.out.println("the port: " + url.getPort());System.out.println("the file: " + url.getFile());System.out.println(url.toString());} catch (MalformedURLException e) {e.printStackTrace();}

        //使用URL类的openstream()方法打开连接,实质还是利用URLConnection
package com.index.network;import jdk.internal.util.xml.impl.Input;import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;/*** URL对象的创建及使用* @author index* @date 2020/9/20**/
public class Myurl {public static void main(String[] args) {try {URL url = new URL("http://www.baidu.com");System.out.println("the Protocol: " + url.getProtocol());System.out.println("the hostname: " + url.getHost());System.out.println("the port: " + url.getPort());System.out.println("the file: " + url.getFile());System.out.println(url.toString());//使用URL类的openstream()方法打开连接InputStream in = url.openStream();int c;System.out.println("输出放回的response:");while((c = in.read()) != -1){System.out.print((char)c);}in.close();} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

源码码:

    /*** Opens a connection to this {@code URL} and returns an* {@code InputStream} for reading from that connection. This* method is a shorthand for:* <blockquote><pre>*     openConnection().getInputStream()* </pre></blockquote>** @return     an input stream for reading from the URL connection.* @exception  IOException  if an I/O exception occurs.* @see        java.net.URL#openConnection()* @see        java.net.URLConnection#getInputStream()*/public final InputStream openStream() throws java.io.IOException {return openConnection().getInputStream();}/*** Returns a {@link java.net.URLConnection URLConnection} instance that* represents a connection to the remote object referred to by the* {@code URL}.** <P>A new instance of {@linkplain java.net.URLConnection URLConnection} is* created every time when invoking the* {@linkplain java.net.URLStreamHandler#openConnection(URL)* URLStreamHandler.openConnection(URL)} method of the protocol handler for* this URL.</P>** <P>It should be noted that a URLConnection instance does not establish* the actual network connection on creation. This will happen only when* calling {@linkplain java.net.URLConnection#connect() URLConnection.connect()}.</P>** <P>If for the URL's protocol (such as HTTP or JAR), there* exists a public, specialized URLConnection subclass belonging* to one of the following packages or one of their subpackages:* java.lang, java.io, java.util, java.net, the connection* returned will be of that subclass. For example, for HTTP an* HttpURLConnection will be returned, and for JAR a* JarURLConnection will be returned.</P>** @return     a {@link java.net.URLConnection URLConnection} linking*             to the URL.* @exception  IOException  if an I/O exception occurs.* @see        java.net.URL#URL(java.lang.String, java.lang.String,*             int, java.lang.String)*/public URLConnection openConnection() throws java.io.IOException {return handler.openConnection(this);}

URLConnection类

URLConnection是一个抽象类,除了connect()方法,其他方法都已经实现。表示指向URL指定资源的活动连接。
子类:

copy一段常用方法:(参考https://www.cnblogs.com/lukelook/p/11236481.html)

String getContentType()返回 Content-type 头字段的值。即数据的MIME内容类型。若类型不可用,则返回null。除了HTTP协议,极少协议会使用MIME首部。若内容类型是文本。则Content-type首部可能会包含一个标识内容编码方式的字符集。例:Content-type:text/html; charset=UTF-8int getContentLength()返回 Content-length 头字段的值。该方法获取内容的字节数。许多服务器只有在传输二进制文件才发送Content-length首部,在传输文本文件时并不发送。若没有该首部,则返回-1。若需要知道读取的具体字节数,或需要预先知道创建足够大的缓冲区来保存数据时,可以使用该方法。String getContentEncoding()返回 Content-encoding 头字段的值。获取内容的编码方式。若内容无编码,则该方法返回null。注意:Content-encoding(内容编码)与字符编码不同。字符编码方式由Content-type首部或稳定内容的信息确定,它指出如何使用字节指定字符。内容编码方式则指出字节如何编码其他字节。例:若编码格式为x-gzip,则可以使用java.util.zip.GZipInputStream来解码。long getDate()返回 date 头字段的值。获取请求的发送时间。即自1900年1月1日子夜后过去的毫秒数。注意:这是从服务器的角度看到的发送时间。可能与本地时间不一致。若首部不包括Date字段,则返回0。long getExpiration()返回 expires 头字段的值。获取Expires的值。若无该字段,则返回0。0即表示不过期,永远缓存。注意:该值是自1970年1月1日上午12:00后的毫秒数。long getLastModified()返回 last-modified 头字段的值。该值是自1900年1月1日子夜后过去的毫秒数。若无该字段,则返回0。

测试与输出:

package com.index.network;import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;/*** 使用URLConnection从Web服务器读取文件* @author index* @date 2020/9/20**/
public class URLDemo {public static void main(String[] args) throws Exception{System.out.println("starting...");int c;URL url = new URL("http://www.baidu.com");URLConnection urlConnection = url.openConnection();System.out.println("the date is :" + new Date(urlConnection.getDate()));System.out.println("content_type:" + urlConnection.getContentType());InputStream in = urlConnection.getInputStream();while(((c = in.read())!= -1))System.out.print((char)c);in.close();}
}

使用URLConnection发送post请求

下面代码copy自:https://blog.csdn.net/bingguang1993/article/details/79943340

1.通过在 URL 上调用 openConnection 方法创建连接对象。
2.处理设置参数和一般请求属性,获取URLconnection实例对应的输出流来发送数据。
3.使用 connect 方法建立到远程对象的实际连接。
4.远程对象变为可用。远程对象的头字段和内容变为可访问。

package com.index.network;import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;/*** 使用URLConnection从Web服务器读取文件* @author index* @date 2020/9/20**/
public class URLDemo {public static String doPost(String posturl,String params) {try {//1.通过在 URL 上调用 openConnection 方法创建连接对象URL url=new URL(posturl);URLConnection conn=url.openConnection();//2.处理设置参数和一般请求属性//2.1设置参数//可以根据请求的需要设置参数conn.setDoInput (true);  //默认为true 所以不设置也可以conn.setDoOutput(true);  //默认为false 发送post请求必须设置setDoOutput(true)conn.setUseCaches(false); //是否可以使用缓存 不使用缓存conn.setConnectTimeout(5000);//请求超时时间//2.2请求属性//设置通用的请求属性 消息报头 即设置头字段 更多的头字段信息可以查阅HTTP协议conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");//2.3设置请求正文 即要提交的数据PrintWriter pw=new PrintWriter(new OutputStreamWriter(conn.getOutputStream()));pw.print(params);pw.flush();pw.close();//3.使用 connect 方法建立到远程对象的实际连接。conn.connect();//4.远程对象变为可用。远程对象的头字段和内容变为可访问。//4.1获取响应的头字段Map<String, List<String>> headers=conn.getHeaderFields();System.out.println(headers); //输出头字段//4.2获取响应正文BufferedReader reader = null;StringBuffer resultBuffer = new StringBuffer();String tempLine = null;reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));while ((tempLine = reader.readLine()) != null) {resultBuffer.append(tempLine);}//System.out.println(resultBuffer);reader.close();return resultBuffer.toString();} catch (MalformedURLException e) {// TODO 自动生成的 catch 块e.printStackTrace();} catch (IOException e) {// TODO 自动生成的 catch 块e.printStackTrace();}finally {}return null;}public static void main(String[] args) throws Exception{System.out.println("starting...");System.out.println("post请求返回的response信息: ");System.out.println(doPost("http://127.0.0.1:8080/login", "username=index&password=123456"));}//"{\"username\":\"index\",\"password\":\"123456\"}"
}

啊输出结果就是登录成功后的页面信息,就不截图了

除了,利用URLConnection,我们其实可以用HttpURLConnection更方便的发送与http有关的get及post请求

例子源于:https://www.cnblogs.com/hsuhung/p/10796739.html
挺详细的。

package com.index.network;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;/*** @author index* @date 2020/9/23**/
public class HttpURLConnectionDemo {/*** POST请求** @param requestUrl 请求地址* @param param 请求数据* @return*/public static String post(String requestUrl, String param) {HttpURLConnection connection = null;InputStream is = null;OutputStream os = null;BufferedReader br = null;String result = null;try {/** 创建远程url连接对象 */URL url = new URL(requestUrl);/** 通过远程url对象打开一个连接,强制转换为HttpUrlConnection类型 */connection = (HttpURLConnection) url.openConnection();/** 设置连接方式:POST */connection.setRequestMethod("POST");/** 设置连接主机服务器超时时间:15000毫秒 */connection.setConnectTimeout(15000);/** 设置读取远程返回的数据时间:60000毫秒 */connection.setReadTimeout(60000);/** 设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个 */// 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为trueconnection.setDoOutput(true);// 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无connection.setDoInput(true);/** 设置通用的请求属性 */connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");/** 通过连接对象获取一个输出流 */os = connection.getOutputStream();/** 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的 */// 若使用os.print(param);则需要释放缓存:os.flush();即使用字符流输出需要释放缓存,字节流则不需要if(param != null && param.length() > 0) {os.write(param.getBytes());}/** 请求成功:返回码为200 */if (connection.getResponseCode() == 200) {/** 通过连接对象获取一个输入流,向远程读取 */is = connection.getInputStream();/** 封装输入流is,并指定字符集 */br = new BufferedReader(new InputStreamReader(is, "UTF-8"));/** 存放数据 */StringBuffer sbf = new StringBuffer();String line = null;while ((line = br.readLine()) != null) {sbf.append(line);sbf.append("\r\n");}result = sbf.toString();}} catch (Exception e) {e.printStackTrace();} finally {/** 关闭资源 */try {if (null != br) {br.close();}if (null != is) {is.close();}if (null != os) {os.close();}} catch (Exception e) {e.printStackTrace();}/** 关闭远程连接 */// 断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。// 固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些connection.disconnect();System.out.println("--------->>> POST request end <<<----------");}return result;}public static void main(String[] args) {System.out.println("starting...");System.out.println("post请求返回的response信息: ");System.out.println(post("http://127.0.0.1:8080/login", "username=index&password=123456"));}
}

Socket类

先举例子,注意java服务端socket默认接收的编码是GBK,客户端发送消息前需要指定编码为GBK。当然咯,也可以指定服务端和接收端的编码格式都为UTF-8

例子参考:https://www.cnblogs.com/linkenpark/p/11289018.html

Server:

package com.index.network.socket;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;/*** @author index* @date 2020/9/23**/public class ServerSocketDemo {public static void main(String[] args) {try {//初始化服务端socket并且绑定9999端口ServerSocket serverSocket = new ServerSocket(9999);//等待客户端的连接Socket socket = serverSocket.accept();//获取输入流BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//读取一行数据String str = bufferedReader.readLine();//输出打印System.out.println(str);} catch (IOException e) {e.printStackTrace();}}
}

Client:

package com.index.network.socket;import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;public class ClientSocketDemo {public static void main(String[] args) {try {Socket socket = new Socket("127.0.0.1", 9999);BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "GBK"));String str = "socket服务端向你发送消息了";bufferedWriter.write(str);//刷新输入流bufferedWriter.flush();//关闭socket的输出流socket.shutdownOutput();} catch (IOException e) {e.printStackTrace();}}
}

先运行Server程序,后运行Client程序,即可在Server端看到响应的输出结果

发送多条消息:
客户端每发送一行,添加一个“\n”标识,服务端就可以读取客户端发来的数据,判断是否到了流的结尾,如果没有到结尾,服务端就会一直阻塞,等待用户新的输入。

Server:

package com.index.network.socket;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;public class ServerSocketDemo2 {public static void main(String[] args) {try {//初始化服务端socket并且绑定9999端口ServerSocket serverSocket = new ServerSocket(9999);//等待客户端的连接Socket socket = serverSocket.accept();//获取输入流,并且指定统一的编码格式BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));//读取一行数据String str;//通过while循环不断读取信息,while ((str = bufferedReader.readLine()) != null) {//输出打印System.out.println(str);}} catch (IOException e) {e.printStackTrace();}}
}

Client:

package com.index.network.socket;import java.io.*;
import java.net.Socket;public class ClientSocketDemo2 {public static void main(String[] args) {try {//初始化一个socketSocket socket = new Socket("127.0.0.1", 9999);//通过socket获取字符流BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));//通过标准输入流获取字符流BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));while (true) {String str = bufferedReader.readLine();bufferedWriter.write(str);bufferedWriter.write("\n");bufferedWriter.flush();}} catch (IOException e) {e.printStackTrace();}}
}

Client输入:

Server输出:

不过上面这种通信是阻塞式的,即客户端A与服务器建立连接的话,客户端B就不能建立连接

解决办法: 在服务端使用多线程
Server:

package com.index.network.socket;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;public class ServerSocketDemo2 {public static void main(String[] args) throws IOException {//初始化服务端socket并且绑定9999端口ServerSocket serverSocket = new ServerSocket(9999);int count = 0;while(true) {//等待客户端的连接Socket socket = serverSocket.accept();new Thread(new Runnable() {@Overridepublic void run() {try {//获取输入流,并且指定统一的编码格式BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));//读取一行数据String str;System.out.println(Thread.currentThread().getName() + ": ");//通过while循环不断读取信息,while ((str = bufferedReader.readLine()) != null) {//输出打印System.out.println(str);}} catch (IOException e) {e.printStackTrace();}}}, "线程" + String.valueOf(count) + ": ").start();}}
}

使用线程池分配线程,而不是每来一个客户端就创建一个线程

Server:

package com.index.network.socket;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ServerSocketDemo3 {public static void main(String[] args) throws IOException {//初始化服务端socket并且绑定9999端口ServerSocket serverSocket = new ServerSocket(9999);//创建一个线程池ExecutorService executorService = Executors.newFixedThreadPool(100);while (true) {//等待客户端的连接Socket socket = serverSocket.accept();Runnable runnable = () -> {BufferedReader bufferedReader = null;try {bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));//读取一行数据String str;//通过while循环不断读取信息,while ((str = bufferedReader.readLine()) != null) {//输出打印System.out.println("客户端说:" + str);}} catch (IOException e) {e.printStackTrace();}};executorService.submit(runnable);}}
}

发送指定类型,指定长度的数据包,而不是向前面那样每次发送都是以/n结尾:

Server:

package com.index.network.socket;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class ServerSocketDemo4 {public static void main(String[] args) {try {ServerSocket serverSocket = new ServerSocket(9999);Socket client = serverSocket.accept();InputStream inputStream = client.getInputStream();DataInputStream dataInputStream = new DataInputStream(inputStream);while (true) {byte b = dataInputStream.readByte();int len = dataInputStream.readInt();byte[] data = new byte[len - 5];dataInputStream.readFully(data);String str = new String(data);System.out.println("获取的数据类型为:" + b);System.out.println("获取的数据长度为:" + len);System.out.println("获取的数据内容为:" + str);}} catch (IOException e) {e.printStackTrace();}}
}

Client:

package com.index.network.socket;import java.io.*;
import java.net.Socket;
import java.util.Scanner;public class ClientSocketDemo4 {public static void main(String[] args) {try {Socket socket =new Socket("127.0.0.1",9999);OutputStream outputStream = socket.getOutputStream();DataOutputStream dataOutputStream =new DataOutputStream(outputStream);Scanner scanner =new Scanner(System.in);if(scanner.hasNext()){String str = scanner.next();int type =1;byte[] data = str.getBytes();int len = data.length +5;dataOutputStream.writeByte(type);dataOutputStream.writeInt(len);dataOutputStream.write(data);dataOutputStream.flush();}}catch (IOException e) {e.printStackTrace();}}
}

DatagramSocket

参考:https://blog.csdn.net/jiangxinyu/article/details/8161044

UDP套接字的使用是通过DatagramPacket类和DatagramSocket类。
UDP客户端和服务端都主要执行如下3个步骤:

1.创建DatagramSocket实例;

2.使用DatagramSocket类的send()和receive()方法发送和接收DatagramPacket实例;

3.最后使用DatagramSocket类的close()方法销毁该套接字。

例子:设置在receive()方法上最多阻塞等待3秒,最多重发次数为5

Server:

package com.index.network.socket;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class UDPEchoServer {private static final int ECHOMAX = 255; // 发送或接收的信息最大字节数public static void main(String[] args) throws IOException {final int servPort = 9999;DatagramSocket socket = new DatagramSocket(servPort);DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX);while (true) { // 不断接收来自客户端的信息及作出相应的响应socket.receive(packet); // Receive packet from clientSystem.out.println("Handling client at " + packet.getAddress().getHostAddress() + " on port " + packet.getPort());socket.send(packet); // 将客户端发送来的信息返回给客户端packet.setLength(ECHOMAX);// 重置packet的内部长度,因为处理了接收到的信息后,数据包的内部长度将被//设置为刚处理过的信息的长度,而这个长度可能比缓冲区的原始长度还要短,//如果不重置,而且接收到的新信息长于这个内部长度,则超出长度的部分将会被截断,所以这点必须注意到。}}
}

Client:

package com.index.network.socket;import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.io.IOException;
import java.io.InterruptedIOException;public class UDPEchoClient {private static final int TIMEOUT = 3000;   // 设置超时为3秒private static final int MAXTRIES = 5;     // 最大重发次数5次public static void main(String[] args) throws IOException {InetAddress serverAddress = InetAddress.getLocalHost(); // 服务器地址// Convert the argument String to bytes using the default encoding//发送的信息byte[] bytesToSend = "UDP客户端,前来报到".getBytes();int servPort = 9999;DatagramSocket socket = new DatagramSocket();socket.setSoTimeout(TIMEOUT); // 设置阻塞时间DatagramPacket sendPacket = new DatagramPacket(bytesToSend, // 相当于将发送的信息打包bytesToSend.length, serverAddress, servPort);DatagramPacket receivePacket =                              // 相当于空的接收包new DatagramPacket(new byte[bytesToSend.length], bytesToSend.length);int tries = 0;      // Packets may be lost, so we have to keep tryingboolean receivedResponse = false;do {socket.send(sendPacket);          // 发送信息try {socket.receive(receivePacket); // 接收信息if (!receivePacket.getAddress().equals(serverAddress)) {// Check sourcethrow new IOException("Received packet from an unknown source");}receivedResponse = true;} catch (InterruptedIOException e) { // 当receive不到信息或者receive时间超过3秒时,就向服务器重发请求tries += 1;System.out.println("Timed out, " + (MAXTRIES - tries) + " more tries...");}} while ((!receivedResponse) && (tries < MAXTRIES));if (receivedResponse) {System.out.println("Received: " + new String(receivePacket.getData()));} else {System.out.println("No response -- giving up.");}socket.close();}
}

服务端将接收到的消息原样返回:

MulticastSocket实现广播

DatagramSocket只允许数据报发送给指定的目标地址,而MulticastSocket可以将数据报以广播的方式发送到多个客户端

MulitcastSocket是DatagramSocket的一个子类,当要发送一个数据报时,可以使用随机端口创建一个MulticastSocket,也可以在指定端口创建MulticastSocket。MulticastSocket提供了如下3个构造器。

1、MulticastSocket():使用本机默认地址、随机端口来创建MulticastSocket对象

2、MulticastSocket(int portNumber)使用本机默认地址、指定端口来创建对象

3、MulticastSocket(SocketAddress bindaddr):使用本机指定IP地址、指定端口来创建对象

创建MulticastSocket对象后,还需要将该MulticastSocket加入到指定的多点广播地址,MulticastSocket使用joinGroup()方法加入指定组;使用leaveGroup()方法脱离一个组。

1、joinGroup(InetAddress multicastAddr):将该MulticastSocket加入指定的多点广播地址。

2、leaveGroup(InetAddress multicastAddr):让该MulticastSocket离开指定的多点广播地址。

例子:将224.0.0.1作为广播地址,监听这个广播地址的listener都算做一个组(通过广播地址向组内的所有Ip地址发送数据包)

ip地址的范围: 参考:https://zhidao.baidu.com/question/53554208.html

其中D类地址是广播地址,D类IP地址范围224.0.0.1-239.255.255.254

listener1:

package com.index.network.socket;import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;public class MulticastSender {private final int port;private final String host;private final String data;public MulticastSender(String data, String host, int port) {this.data = data;this.host = host;this.port = port;}public void send() {try {InetAddress ip = InetAddress.getByName(this.host);DatagramPacket packet = new DatagramPacket(this.data.getBytes(), this.data.length(), ip, this.port);MulticastSocket ms = new MulticastSocket();ms.send(packet);ms.close();} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) throws UnknownHostException {int port = 1234;String host = "224.0.0.1";String data = "hello world.";System.out.println(data);MulticastSender ms = new MulticastSender(data, host, port);ms.send();}
}

listener2:

package com.index.network.socket;import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;public class MulticastListener2 {private final int port;private final String host;public MulticastListener2(String host, int port) {this.host = host;this.port = port;}public void listen() {byte[] data = new byte[256];try {InetAddress ip = InetAddress.getByName(this.host);MulticastSocket ms = new MulticastSocket(this.port);ms.joinGroup(ip);DatagramPacket packet = new DatagramPacket(data, data.length);//receive()是阻塞方法,会等待客户端发送过来的信息ms.receive(packet);String message = new String(packet.getData(), 0, packet.getLength());System.out.println(message);ms.close();} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) throws UnknownHostException {int port = 1234;String host = "224.0.0.1";MulticastListener ml = new MulticastListener(host, port);while (true) {ml.listen();}}
}

sender:

package com.index.network.socket;import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;public class MulticastSender {private final int port;private final String host;private final String data;public MulticastSender(String data, String host, int port) {this.data = data;this.host = host;this.port = port;}public void send() {try {InetAddress ip = InetAddress.getByName(this.host);DatagramPacket packet = new DatagramPacket(this.data.getBytes(), this.data.length(), ip, this.port);MulticastSocket ms = new MulticastSocket();ms.send(packet);ms.close();} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) throws UnknownHostException {int port = 1234;String host = "224.0.0.1";String data = "hello world.";System.out.println(data);MulticastSender ms = new MulticastSender(data, host, port);ms.send();}
}

运行结果就是一个sender发送,2个listener接收相同的消息

Java网络编程socket基础学习相关推荐

  1. Java网络编程与NIO学习总结

    #Java网络编程与NIO学习总结 这篇总结主要是基于我之前Java网络编程与NIO系列文章而形成的的.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 #更多详细内容可 ...

  2. Java网络编程 Socket、ServerSocket 详解,方法介绍及完整代码示例

    Java网络编程 Socket.ServerSocket 详解,方法介绍及完整代码示例 概念 什么是网络编程? 网络编程是指编写运行在多个设备(计算机)的程序,这些设备通过网络连接起来.当这些通过网络 ...

  3. java网络编程socket\server\TCP笔记(转)

    java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04|  分类: Socket |  标签:java  |举报|字号 订阅 1 TCP的开销 a  连接 ...

  4. Java网络编程——Socket 编程

    Socket 编程 Socket编程是在TCP/IP上的网络编程,但是Socket在上述模型的什么位置呢.这个位置被一个天才的理论家或者是抽象的计算机大神提出并且安排出来 我们可以发现Socket就在 ...

  5. java网络编程_Java基础 网络编程

    主要内容 软件架构CS/BS 网络通信三要素 TCP通信 Socket套接字 ServerSocket 教学目标 能够辨别UDP和TCP协议特点 能够说出TCP协议下两个常用类名称 能够编写TCP协议 ...

  6. JAVA网络编程Socket常见问题 【长连接专题】

    一. 网络程序运行过程中的常见异常及处理 第1个异常是 java.net.BindException:Address already in use: JVM_Bind. 该异常发生在服务器端进行new ...

  7. 网络编程Socket基础

    Socket能够实现网络上的不同主机之间或同一主机的不同对象之间的数据通信.所以,Socket已经是一类通用通信接口的集合. 地址表示数据结构   IP协议使用的地址描述数据结构,使用需要包括头文件n ...

  8. JAVA并发编程JUC基础学习(简介)

    2019独角兽企业重金招聘Python工程师标准>>> 之前写过一篇并发编程的简单实例应用,Future快速实现并发编程,可以很快的在自己的项目中应用,但并不系统,之前说过总结一篇( ...

  9. WebService 及java网络编程等基础概念(一)

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接: https://blog.csdn.net/u014401141/article/ ...

最新文章

  1. 【CLR的执行模型:将源代码编译成托管模块】
  2. docker保存linux镜像,docker导入导出容器和保存加载镜像
  3. git 提交命令_Git和Github快速上手指南
  4. Clubhouse 本土化之后干得过“顶流”抖音快手吗? | 极客视频
  5. C++之多态性与虚函数
  6. 为了方便读者检索和阅读以往的内容,已开通“号内搜”功能
  7. 为什么下载源码包需要到官网上去下载?
  8. imp导入前对当前用户清库脚本
  9. 使用 Packer、Ansible 和 Terraform 构建不可变的基础设施Devops工具链
  10. 小白学习倍福的必经之路
  11. 【AVL】宠物收养所
  12. 运算符、表达式和语句
  13. 抖音的商业定位和内容定位
  14. 小米天气api html,小米天气app
  15. XAML中的Style
  16. char类型的大小范围
  17. c#调用TeamViewer或AnyDesk实现远程控制
  18. 实时无感人脸识别考勤机项目
  19. 【 STM32实例 】 智能小车的红外循迹
  20. 大盘点!国内外深度相机汇总

热门文章

  1. 转:要使一个人有一颗自由、独立、勇敢的心
  2. pfamscan 的使用_InterProScan的使用教程
  3. 文件包含漏洞(完整版)
  4. Hudi on Flink在顺丰的实践应用.ppt
  5. 在线使用ChatGPT,国内手机号也可以注册。
  6. 搭建个人网站--域名申请
  7. Linux 邻居子系统介绍
  8. 多对多关系需要建立中间表_【数据库基础】为什么需要三张表之多对多表结构设计...
  9. Vulnhub-theEther
  10. 从CNCB下载单细胞转录组fastq文件并定量