SOCKET编程学习
1、基础知识整理
/** * 一、网络编程中的两个问题 * 1、如何准确的定位网络上一台或多台主机并且定位主机上的应用 * 2、找到主机后如何可靠高效的进行数据传输 * 二、解决办法 * 1、对应问题一:IP和端口 * 2、对应问题二:提供网络通信协议 TCP/IP模型(应用层、传输层、网络层、物理层) * 数据传输按照这样规定的规则协议来传输,并且每一层有具体的协议例如应用层(http、FTP) * 传输层(TCP、UDP)、网层层(IP) * * 三、IP 和端口具体了解 * Java中InetAddress这个类代表一个IP * DNS 域名服务解析器 用来解析域名的 * IP+端口 组合起来叫 网络套接字 socket,可以理解成网络中的一个节点 * 四、网络通信协议具体了解 * 1、分为四层 应用层 传输层 网络层 物理层 每一层解决不同的问题,同层之间可以通信,层与层之间进行彼此通信,不能隔层通信 * 2、传输层有两个重要的协议 TCP(传输控制协议)、UDP(用户数据报协议)传输层和网络层 组合在一起叫TCP/IP协议簇 * 3、TCP的建立链接和断开链接需要三次握手和4次挥手数据安全可靠、UDP不用,只管发消息类似与发垃圾短息,数据不安全会丢数据 * UDP可以用在视频传播这里,即使丢一点数据也不影响观看 * 五、TCP编程或者UDP编程 * TCP编程或者UDP编程也叫socket编程 * * * */
2、InetAddress常见的API
public class IntenetAddressTest { public static void main(String[] args) { try{ InetAddress inetAddress = InetAddress.getByName("192.168.1.19"); System.out.println(inetAddress); InetAddress inet = InetAddress.getByName("www.baidu.com"); System.out.println(inet); InetAddress local = InetAddress.getLocalHost(); System.out.println(local); InetAddress loop = InetAddress.getLoopbackAddress(); System.out.println(loop); //获取域名 System.out.println(loop.getHostName()); //获取域名对应的ip System.out.println(loop.getHostAddress()); }catch (Exception e){ } } }
3、TCP编程
3.1 服务端代码
@RestController public class ProviderController { @RequestMapping("/provider") public void provider(){ ServerSocket serverSocket = null; Socket socket = null; InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; try{ byteArrayOutputStream = new ByteArrayOutputStream(); byte[] bytes = new byte[5]; int len; //这里不用指定ip,程序跑在哪里就用当前服务器的ip,源码里面有获取ip的方法 serverSocket = new ServerSocket(8015); //一直监听着端口,这个端口不能和server.port重复 while (true){ socket = serverSocket.accept(); inputStream = socket.getInputStream(); while ((len = inputStream.read(bytes))!= -1){ byteArrayOutputStream.write(bytes,0,len); } System.out.println(byteArrayOutputStream.toString()); // byteArrayOutputStream.reset(); System.out.println("收到了来自于"+socket.getInetAddress().getHostAddress()+"的数据"); } }catch (Exception e){ }finally { try{ if(byteArrayOutputStream != null){ byteArrayOutputStream.close(); }if(inputStream != null){ inputStream.close(); }if(socket !=null){ socket.close(); }if(serverSocket !=null){ serverSocket.close(); } }catch (Exception e){ } } } }
3.2 客户端代码
@RestController public class ConsumerController { // @RequestMapping("/consumer") public void consumer(){ OutputStream outputStream = null; Socket socket = null; try{ //对方的ip InetAddress inetAddress = InetAddress.getByName("127.0.0.1"); //这个端口不能和server.port重复 socket = new Socket(inetAddress,8015); outputStream = socket.getOutputStream(); outputStream.write("你好 我是客户端 mm".getBytes()); outputStream.close(); socket.close(); }catch (Exception e){ }finally { try{ if(outputStream != null){ outputStream.close(); }if(socket != null){ socket.close(); } }catch (Exception e){ } } } }
3.3 测试结果
4、UDP编程
4.1 服务端
/** * * UDP测试服务端 * */ @RestController public class UDPServerController { private final int MAX_SIZE = 1024; private final int PORT = 8080; private DatagramSocket socket; @RequestMapping("/reveiceUdp") public void receiveUdpdata() throws Exception{ try { //这里不用指定IP但是端口一定要指定 socket = new DatagramSocket(PORT); System.out.println("UDP server start."); int count = 0; while(true) { byte[] buffer = new byte[MAX_SIZE]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); String data = new String(packet.getData(),0,packet.getLength()); System.out.println("server receive data : "+data); //服务端响应给客户端的消息 byte[] send = String.format("yes,udp server. %d times", count++).getBytes(); packet.setData(send); socket.send(packet); } } catch (Exception e) { e.printStackTrace(); }finally { socket.close(); } } }
4.2 客户端
/** * * UDP测试 * * */ @RestController public class UDPConsumerController { @RequestMapping("/sendUdpData") public void udpTest()throws Exception{ String str = "我是 udp 方式发送的导弹"; byte[] data = str.getBytes(); //创建一个socket DatagramSocket socket = null; try { // 这里用用带参的构造器,不用带参的发不出去消息 socket = new DatagramSocket(10000); int port = 8080; //地址 InetAddress inetAddress = InetAddress.getLocalHost(); /** * 创建数据包用下面的构造器 * 1、报文 * 2、从哪里开始发 * 3、发多长 * 4、服务端的地址 * 5、端口号 */ DatagramPacket packet = new DatagramPacket(data, data.length, inetAddress, port); //显示的调用API 来发送信息,这个和TCP编程还不一样哈。 socket.send(packet); //接收服务端给的响应日志 byte[] buffer = new byte[1024]; DatagramPacket receiver = new DatagramPacket(buffer, buffer.length); socket.receive(receiver); String res = new String(receiver.getData(),0,receiver.getLength()); System.out.println("response by server : "+res); } catch (Exception e) { e.printStackTrace(); }finally { socket.close(); } } }
4.3 测试结果
先启动服务端然后启动客户端发消息