第四课:Socket

Posted Vanau

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第四课:Socket相关的知识,希望对你有一定的参考价值。


一.InetAddress类

package inetAddress;

import java.io.*;
import java.net.*;

public class InetAddressTest

    public static void main(String[] args) throws IOException 
    
        if(args.length>0)
        
            String host=args[0];
            InetAddress addresses=InetAddress.getByName(host);
            System.out.println("链接ip:"+addresses.getHostAddress());
            System.out.println("链接主机名:"+addresses.getHostName());
        
        else 
        
            InetAddress localHostAddress=InetAddress.getLocalHost();
            System.out.println("本地ip:"+localHostAddress.getHostAddress());
            System.out.println("本地主机名:"+localHostAddress.getHostName());
        
    

第一种情况(if):
设置main函数输入参数:

得到结果:

或者直接在控制台:

第二种情况(else):


二.UDP
网络通讯一般称为Socket(套接字)通讯,要求通讯的两台机器都必须要安装Socket。对于不同的协议就有不同的Socket。

  1. UDP通讯的特点:
    1.讲数据及其源/目的封装为数据包,面向无连接。
    2.每个数据包大小限制在64k中。
    3.因为无连接,所以不可靠,容易丢包。
    4.因为不需要建立连接,所以速度快。
    5.udp通讯是不分服务端和客户端的,只分发送端和接收端。
  2. udp协议下的Socket:
    DatagramSocket(udp套接字服务类)
    DatagramPacket(数据包类)

  3. 在udp协议中,有一个ip地址称作为广播地址,广播地址就是主机号为255的地址。在给广播地址发送消息的地址,在同一个网络段的机器都可以接收的到信息。
    比如C类地址:192.168.12.255(前24位是网络号,后8位是主机号,也就是该主机号为255,则往广播地址发送消息的时候,ip地址为192.168.12.* 的都可以接收的到)。

//------------------SendPort.java
package udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class SendPort 

    public static void main(String[] args) throws IOException 
    
        //建立UDP的服务
        DatagramSocket sendSocket=new DatagramSocket();
        //准备数据,讲数据封装到数据包中
        String data="这是第一个udp的栗子!!!";
        DatagramPacket packet=new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getLocalHost(), 9090);
        //String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组。
        /*      
        DatagramPacket(buf,length,address,port);
        buf:发送的数据内容
        length:发送数据内容的大小
        address:发送的目的ip地址对象
        port:端口号
        */  
        //发送数据包
        sendSocket.send(packet);
        sendSocket.close();
    
//---------------------ReceivePort.java
package udp;

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceivePort 

    public static void main(String[] args) throws IOException 
    
        //建立udp服务,并且监听一个端口
        DatagramSocket receiveSocket=new DatagramSocket(9090);
        //准备空的数据包用于存放数据
        byte[] buf=new byte[1024];
        DatagramPacket datagramPacket=new DatagramPacket(buf, buf.length);
        //调用udp的服务接收数据.注:receive方法在接收到数据前此进程一直被阻塞
        receiveSocket.receive(datagramPacket);
        System.out.println("接收端接收到的数据:"+new String(buf,0,datagramPacket.getLength()));
        receiveSocket.close();
    

首先在控制端启动接收端进程:

再在eclipse中启动发送端进程:得到结果如上图所示。


三.群聊

//-----------------------------Sender,java
package ChatTest;

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Sender implements Runnable

    public void run() 
    
        try 
        
            DatagramSocket senderSocket=new DatagramSocket();
            BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
            String line=null;
            while ((line=reader.readLine())!=null) 
            
                DatagramPacket senderPacket=new DatagramPacket(line.getBytes(),line.getBytes().length, 
                                            InetAddress.getByName("192.168.23.255"), 9090);
                senderSocket.send(senderPacket);                    
            
            senderSocket.close();
         
        catch (Exception e) 
        
            System.out.println("Send failed...");
            e.printStackTrace();
               
    

//----------------------------Receiver.java
package ChatTest;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Receiver implements Runnable

    public void run() 
    
        try 
        
            DatagramSocket receiveSocket =new DatagramSocket(9090);
            byte[] buf=new byte[1024];
            while(true)
            
                DatagramPacket receivepPacket=new DatagramPacket(buf, buf.length);
                receiveSocket.receive(receivepPacket);
                System.out.println("接收到来自 "+receivepPacket.getAddress().getHostAddress()+
                                    " 的消息 : "+new String(buf,0,receivepPacket.getLength()));
                //System.out.println();
            
         
        catch (Exception e) 
        
            System.out.println("Receive failed...");
            e.printStackTrace();
               
    

//------------------------------Main.java
package ChatTest;

public class Main 

    public static void main(String[] args) 
    
        Runnable senderRunnable=new Sender();
        Thread senderThread=new Thread(senderRunnable);
        senderThread.start();

        Runnable receiverRunnable=new Receiver();
        Thread receiveThread=new Thread(receiverRunnable);
        receiveThread.start();          
    


四.TCP

  1. 特点:
    1.tcp是基于IO流进行数据传输的。
    2.tcp进行数据传输的时候没有大小限制。
    3.tcp通过三次握手的机制保证数据的完整性,它是一种可靠协议。
    4.tcp是面向连接的,所以速度相对而言比较慢。
    5.tcp是区分服务端和客户端的。
  2. tcp协议下的Socket
    Socket(客户端类)– –tcp客户端一旦启动马上要与服务端进行连接。
    SeverSocket(服务端类)
//-------------------------Client.java
package tcp;

import java.io.IOException;
import java.io.*;
import java.net.*;
/*
Socket(String host,int port) 构建一个套接字,用来连接指定的主机和端口。
其等价于:Socket()+void connect(SocketAddress address)
*/
public class Client

    public static void main(String[] args) throws IOException 
    
        //建立tcp的服务
        Socket socket=new Socket(InetAddress.getLocalHost().getHostAddress(),9090);
        //获取向套接字写出数据流的对象
        OutputStream outputStream= socket.getOutputStream();
        //利用输出流对象写数据
        outputStream.write("服务端你好!我是客户端.".getBytes());
        socket.close();
       

//---------------------------Server.java
package tcp;

import java.io.IOException;
import java.io.*;
import java.util.*;
import java.net.*;

public class Server 

    public static void main(String[] args) throws IOException 
    
        //建立tcp服务端,并且监听一个端口
        ServerSocket serverSocket=new ServerSocket(9090);
        //接收客户端的连接。accept()方法也是一个阻塞型的方法
        Socket incoming =serverSocket.accept();
        //获取输入流对象,读取客户端发送的内容
        InputStream inputStream=incoming.getInputStream();
        byte[] buf=new byte[1024];
        int length=0;
        length=inputStream.read(buf);
            System.out.println("服务端接收:"+new String(buf,0,length));
        serverSocket.close();
    

同样在命令行先启动服务端,再在eclipse窗口中启动客户端,得到结果:

//-------------------------将上面的Client.java换成这个,可以手动输入数据的
package tcp;

import java.io.*;
import java.net.*;
import java.util.*;

/*
Socket(String host,int port) 构建一个套接字,用来连接指定的主机和端口。
其等价于:Socket()+void connect(SocketAddress address)
*/

public class Client

    public static void main(String[] args) throws IOException 
    
        //建立tcp的服务
        Socket socket=new Socket(InetAddress.getLocalHost().getHostAddress(),9090);
        //获取向套接字写出数据流的对象
        OutputStream outputStream= socket.getOutputStream();

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(outputStream));            
        String line=null;
        while (((line=bufferedReader.readLine())!=null)) 
        
            bufferedWriter.write(line);
            bufferedWriter.flush();
               
        socket.close();
       

同样可以得到结果。

以上是关于第四课:Socket的主要内容,如果未能解决你的问题,请参考以下文章

第四课——mysql配置参数讲解

进阶第四课 Python模块之os

第四课试卷讲解 磁盘

第四课 《学习工作回顾记录》

第四课:通过配置文件获取对象(Spring框架中的IOC和DI的底层就是基于这样的机制)

第四课 牛顿方法