概念

网络编程分为BIO(传统IO)、NIO、AIO。Socket编程属于BIO这种传统IO。

InetAddress

  java.net.InetAddress是JAVA中管理IP地址的类,常用

  

  

   public static void main(String[] args) throws UnknownHostException {InetAdressDemo.getLocalHost();System.out.println("---------------------------");getHostByName("Lenovo-Autumn");}/*** 获取主机ip和主机名* @throws UnknownHostException*/public static void getLocalHost() throws UnknownHostException {//根据InetAddress获取主机名和主机ipInetAddress localHost = InetAddress.getLocalHost();System.out.println(localHost);   //打印:Lenovo-Autumn/192.168.56.1//根据getLocalHost()返回的值获取ip和主机名String hostName = localHost.getHostName();String hostAddress = localHost.getHostAddress();System.out.println(hostName); //打印 Lenovo-AutumnSystem.out.println(hostAddress); //打印 192.168.56.1//根据切割获取主机名和ipString[] str = localHost.toString().split("/");System.out.println(str[0]); //打印 Lenovo-AutumnSystem.out.println(str[1]); //打印 192.168.56.1
    }/*** 根据主机名称获取ip地址* @param otherName  主机名(可以是局域网中的机器名或者是域名或者是ip)* @throws UnknownHostException*/public static void getHostByName(String otherName) throws UnknownHostException {InetAddress otherHost = InetAddress.getByName(otherName);String hostName = otherHost.getHostName();String hostAddress = otherHost.getHostAddress();System.out.println(hostName); //打印 Lenovo-AutumnSystem.out.println(hostAddress); //打印 192.168.56.1System.out.println(otherHost);   //打印:Lenovo-Autumn/192.168.56.1}

  code

UDP

  发送数据时必须指定接收端的IP地址和端口号,就好像发送货物的集装箱上面必须标明接收人的地址一样。

  接收端不需要明确知道数据的来源,只需要接收到数据即可。

  java.net.DatagramPackage

构造函数:

第一种是用来接受的数据包,不需要指定IP和端口,第二种是用来发送的数据包需要指定ip和端口

方法:

获取ip地址,获取服务器ip或者客户端ip

  

  返回端口号,获取发送方或者

  返回数据缓冲区

  

  返回要发送或接受的数据包大小

  java.net.DatagramSocket

  DatagramPacket数据包的作用就如同是“集装箱”,可以将发送端或者接收端的数据封装起来。然而运输货物只有“集装箱”是不够的,还需要有码头。在程序中需要实现通信只有DatagramPacket数据包也同样不行,为此JDK中提供的一个DatagramSocket类。DatagramSocket类的作用就类似于码头,使用这个类的实例对象就可以发送和接收DatagramPacket数据包,发送数据的过程如下图所示。

构造函数:

用来创建发送端的DatagramSocket对象

用来创建接收端的DatagramSocket对象

  方法:

发送数据报包

接收数据报包

发送端

1,  创建DatagramSocket对象

DatagramSocket()

2,创建DatagramPacket对象,封装数据,并指定ip和端口。

    DatagramPacket(byte[] buf, int length, InetAddress address, int port)  

3,发送数据

    socket.send(DatagramPacket dp)

4,释放流资源

ds.close();

接收端

1,创建DatagramSocket对象,只需要指定端口

    DatagramSocket(port)

2,创建DatagramPacket对象

    DatagramPacket(byte[] data, int length)

3,接收数据存储到DatagramPacket对象中 

    receive(DatagramPackage dp)

4,获取DatagramPacket对象的内容   

    new String(data,0,dp.getLength());

5,释放流资源

    ds.close();

/*** 实现udp发送端*  用java.net.DatagramPackage封装数据*  用java.net.DatagramSocket发送数据** 实现步骤*  1.用DatagramPackage对象,封装数据,接受的地址和端口*  2.创建DatagramSocket*  3.调用DatagramSocket对象send方法,发送数据*  4.关闭资源**  DatagramPackage构造函数*    DatagramPacket(byte[] buf, int length, InetAddress address, int port)*  DatagramSocket构造函数*    DatagramSocket()*    方法:send(DatagramPacket d)*  Created by Autumn on 2018/2/5.*/
public class UdpSend {public static void main(String[] args) throws Exception {Scanner scanner = new Scanner(System.in);//获取地址InetAddress inet = InetAddress.getByName("127.0.0.1");//创建DatagramSocket,负责接受和发送数据DatagramSocket ds = new DatagramSocket();while(true){String msg = scanner.nextLine();//创建数据包对象对象byte[] data = msg.getBytes();//封装数据,接受的地址和端口DatagramPacket dp = new DatagramPacket(data,data.length,inet,6000);//发送数据包
            ds.send(dp);if(msg.equals("exit")){break;}}//关闭
        ds.close();}
}/***  实现udp接收端*  用java.net.DatagramPackage 接受数据*  用java.net.DatagramSocket 接受数据包**  步骤*  1.创建DatagramSocket对象,绑定端口号(要和发送端端口一致)*  2.创建字节数组用来接受数据*  3.创建数据对象包DatagramPackage*  4.创建DatagramSocket*    receive(DatagramPackage dp)接受数据,将数据封装如dp中*  5.拆包*    发送端的ip地址(DatagramPackage.get)*    接受到的字节数组*    发送的端口号*  6.关闭资源* Created by Autumn on 2018/2/5.*/
public class UdpReceive {public static void main(String[] args) throws IOException {//创建数据包传输的对象,并绑定端口号DatagramSocket ds = new DatagramSocket(6000);//创建字节数组byte[] data = new byte[1024];while(true){//创建数据包对象,传递字节数组DatagramPacket dp = new DatagramPacket(data,data.length);//调用ds对象的receive接受数据包,receive()有线程阻塞效果会一直等待接受数据
            ds.receive(dp);//获取数据包大小int len = dp.getLength();//获取发送端的ip地址InetAddress sendAddress = dp.getAddress();String sendHostAddress = sendAddress.getHostAddress();//System.out.println(sendHostAddress);//获取发送端端口号int port = dp.getPort();//System.out.println(port);//System.out.println(new String(data));   //直接打印1024个字节的字符串,有很多空格System.out.println(sendHostAddress+":"+port+"    "+new String(data,0,len));   //这样打印没有多余的空格if(new String(data,0,len).equals("exit")){break;}}//关闭
        ds.close();}
}

  code

TCP

ServerSocket类,用于表示服务器端,Socket类,用于表示客户端。建立连接后用流进行输入和输出

ServerSocket

   实例化一个ServerSocket类,指定端口号

  监听并接受此套接字的连接

  返回此服务器套接字的本地地址

  Socket

  实例化一个Socket并指定ip和端口

  

返回一个输出流,用于客户端发送数据

  返回一个输入流,用于服务器端接受数据

  

  返回ip地址(服务器端的地址)

  返回端口号

客户端

1,创建客户端的Socket对象,指定服务器IP和端口号

  Socket(String host, int port)

2,获取Socket的输出流对象

  getOutputStream();

3,写数据给服务器

  out.write("服务器数据".getBytes());

4,关闭流资源

  socket.close();

服务器端

1,创建服务器端ServerSocket对象,指定服务器端端口号

  ServerSocket(int port)

2,开启服务器,等待着客户端Socket对象的连接,如有客户端连接,返回客户端的Socket对象

  accept()

3,通过客户端的Socket对象,获取客户端的输入流,为了实现获取客户端发来的数据

  socket.getInputStream();

4,通过客户端的输入流,获取流中的数据

byte[] data = new byte[1024];
int len = inputStream.read(data);
System.out.println(new String(data,0,len));

5,通过客户端的Socket对象,获取客户端的输出流,为了实现给客户端反馈信息

6,通过客户端的输出流,写数据到流中

7,关闭流资源

socket.close();
serverSocket.close();

/*** 实现TCP服务器程序* 表示服务器程序的类java.net.ServerSocket* 构造方法:*      ServerSocket(int port);   传递端口号** Important:必须获得客户端的套接字(Socket)*     方法:Socket accept()*     服务器可以获取到客户端的套接字* Created by Autumn on 2018/2/5.*/
public class TCPServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8888);//调用服务器套接字对象accept()获取客户端套接字,具有线程等待效果Socket socket = serverSocket.accept();    //这里会阻塞等待连接接入    cmd中telnet 127.0.0.1 8888即可连接//根据获得的客户端的socket获取输入流InputStream inputStream = socket.getInputStream();//根据输入流将数据读入到data中byte[] data = new byte[1024];int len = inputStream.read(data);   //这里会阻塞,等待数据   cmd中ctrl+]进入到telnet操作模式send value发送数据System.out.println(new String(data,0,len));socket.close();serverSocket.close();}
}/*** 实现TCP客户端,连接到服务器* 和服务器实现数据交换* 实现TCP客户端程序的类 java.net.Socket** 构造方法:*      Socket(String host, int port)传递服务器IP和端口号*      注意:构造方法只要运行,就会和服务器进行连接,连接时报,抛出异常**      OutputStream    getOutputStream()  返回套接字的输出流*          作用:将数据输出,输出到服务器*      InputStream    getInputStream()  返回套接字的输入流*          作用:从服务器端读取数据**      客户端服务器数据交换,必须使用套接字对象Socket中的获取的IO刘,自己new的流不行** Created by Autumn on 2018/2/5.*/
public class TCPClient {public static void main(String[] args) throws IOException {//创建Socket对象,连接服务器Socket socket = new Socket("127.0.0.1",8888);//通过客户端的套接字对象Socket方法,获取字节输出流,将数据写向服务器OutputStream out = socket.getOutputStream();out.write("这是一条来客户端的数据".getBytes());socket.close();}
}

用cmd命令telnet实现和SocketServer互动

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TCPServer {/*同步阻塞*/public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8888);System.out.println("服务端启动成功...");while(true){/*一次只能处理一个连接,在一个连接没关闭前无法接收第二个连接,在这里开一个框发送数无问题,开放两个框时会出现第二个无反应*/Socket socket = serverSocket.accept();   //这里会阻塞等待连接接入    cmd中telnet 127.0.0.1 8888即代表连接System.out.println("新客户端连接成功....");InputStream inputStream = socket.getInputStream();while(true) {byte[] data = new byte[1024];System.out.println("正在等待数据...");int len = inputStream.read(data);    //这里会阻塞,等待数据,如果直接关闭cmd窗口会因为关闭socket通道导致len返回-1   cmd中ctrl+]进入到telnet操作模式send value发送数据if (len != -1){System.out.println(new String(data, 0,len, "GBK"));   //用GBK是因为CMD窗口命令发送的数据是GBK编码}else{break;}}}//socket.close();//serverSocket.close();//System.out.println("服务器端关闭....");
    }
}

连接服务端

向服务端发送数据

再开一个cmd然后telnet发送数据,发现无反应。必须关闭第一个cmd才能连接成功。

线程池改进,能并发访问

用ExecutorService线程池实现每一个连接创建一个新的线程

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TCPServer {/*异步阻塞*/public static void main(String[] args) throws IOException {ExecutorService threadPool = Executors.newCachedThreadPool();   //线程池ServerSocket serverSocket = new ServerSocket(8888);System.out.println("服务端启动成功...");while(true){/*一次只能处理一个连接,在一个连接没关闭前无法接收第二个连接,在这里开一个框发送数无问题,开放两个框时会出现第二个无反应*/System.out.println("等待客户端连接...");final Socket socket = serverSocket.accept();   //这里会阻塞等待连接接入    cmd中telnet 127.0.0.1 8888即代表连接threadPool.execute(new Runnable() {   //启动一个线程public void run() {try {System.out.println("新客户端连接成功....");InputStream inputStream = socket.getInputStream();while(true) {byte[] data = new byte[1024];System.out.println("正在等待数据...");int len = inputStream.read(data);    //这里会阻塞,等待数据,如果直接关闭cmd窗口会因为关闭socket通道导致len返回-1   cmd中ctrl+]进入到telnet操作模式send value发送数据if (len != -1){System.out.println(Thread.currentThread()+new String(data, 0,len, "GBK"));   //用GBK是因为CMD窗口命令发送的数据是GBK编码}else{System.out.println("break循环");break;}}System.out.println("一次Socket连接关闭");} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}});}//socket.close();//serverSocket.close();//System.out.println("服务器端关闭....");
    }
}

优点:传输质量好(所以BIO适合传输连接少但是数据量大的请求)

缺点:每一个连接都占用一个线程,很占用系统资源。

tip:所有的调优都关联到系统资源(IO、存储、内存、CPU)

code

转载于:https://www.cnblogs.com/aeolian/p/8417916.html

java网络编程之Socket编程相关推荐

  1. 浅谈Java网络编程之Socket (2)

    <浅谈Java网络编程之Socket (1)>中我们已经和大家说到客户端的网络编程,下面和大家分享的是服务器的实现代码. import java.net.*; import java.io ...

  2. Java网络编程之NIO编程(待补充)

    Java网络编程之NIO编程(待补充) 学习网站1:http://ifeve.com/java-nio-all/ 学习网站2:http://www.ibm.com/developerworks/cn/ ...

  3. 浅谈Java网络编程之Socket (1)

    和大家一起分享的是Java网络编程之Socket.在Java中Socket可以理解为客户端或者服务器端的一个特殊的对象,这个对象有两个关键的方法,一个是getInputStream方法,另一个是get ...

  4. JAVA网络编程之Socket

    Socket网络编成是一种较为底层的网络数据传输,很多语言都支持. 本例是根据菜鸟教程中的Java网络编程而写. 详细内容参考请参考:http://www.runoob.com/java/java-n ...

  5. 网络编程之 Socket 编程 一文看懂

    但使龙城飞将在,只缘身在此山中 之前在 BIO.NIO 入门(Netty 先导) 一文中聊了 socket ,本文想把视野拉大,从计算机网络的纬度来聊聊 socket 温故而知新,聊聊网络模型 上图对 ...

  6. 网络编程之 socket编程

    socket编程(基于linux下的网络编程) 提起网络编程那么我们就不得不说一下socket编程了(本博客主要是围绕下面这本书展开的). 感谢bingo大佬提供的书籍 链接: https://pan ...

  7. Python网络编程之socket编程

    什么是Socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 ...

  8. linux网络编程之socket编程(六)

    经过一个国庆长假,又有一段时间没有写博文了,今天继续对linux网络编程进行学习,如今的北京又全面进入雾霾天气了,让我突然想到了一句名句:"真爱生活,珍惜生命",好了,言归正传. ...

  9. 超详细的逐句介绍Java网络编程之Socket类函数源码讲解(全)

    一.Socket类 Socket 类表示通信双方中的客户端,用于呼叫远端机器上的一个端口,主动向服务器端发送数据(当连接建立后也能接收数据).下面我将从源码的角度来介绍Socket类的内部原理及其方法 ...

最新文章

  1. java中图片文件的判断
  2. uva 1416 (SPFA) **月赛第E题的原题**
  3. SpringBoot实用小技巧之动态设置SpringBoot日志级别
  4. rancher的微服务运维
  5. 10款微信公众平台相关的开源软件(转)
  6. Spring Data MongoDB级联保存在DBRef对象上
  7. python中字符串乘法_python leetcode 字符串相乘实例详解
  8. C++继承时名字的遮蔽
  9. 埃森哲:AI成新生产要素,2035年将中国经济增速提高1.6% | 附下载
  10. 使用SQL2005 递归查询结合Row_Number()实现完全SQL端树排序
  11. windows10下Qt安装及OpenCV配置
  12. 计算机指法标准,计算机键盘指法的正确练习步骤
  13. 神经内分泌肿瘤如何分级,神经系统分级调节概念
  14. tcl文件调用c语言,TCL与c/c++的互相调用
  15. 一、注册功能怎么测试
  16. 【教程】如果公司的网络屏蔽了游戏【英雄联盟】的链接请求,使用这种方法玩游戏。...
  17. html ppt播放音乐,PPT怎么控制音乐暂停后继续播放?
  18. 2023年国内十大SaaS软件公司排名
  19. WC .exe C语言实现
  20. 震惊!十六岁少女竟然被三名阿里p8老师讲解{常见面试题汇总}

热门文章

  1. crontab中执行postgresql命令
  2. 粒子滤波实现物体跟踪
  3. 在进行文字自绘时,自动换行打印
  4. PADS 9.5安装教程附安装包资源
  5. linux 并行执行脚本,在bash / linux中并行运行shell脚本
  6. 打开ADS提示23111@localhost后提示无法与执照伺服机连线,怎么解决?
  7. linux系统下用GCC、JAVA和Python编程
  8. 让数组的左边全为奇数C语言,2015年全国计算机等级考试全真模拟考场_二级C语言试卷四.docx...
  9. mysql索引组织结构_MySQL中创建及优化索引组织结构的思路(3)
  10. 小程序云服务器选什么系统好,小程序云服务器操作系统选择