第四课: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();
    }   
}

同样可以得到结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值