java:网络编程(InetAddress,InetSocketAddress,URL,TCP(Socket与SeverSocket),TCP与UDP的区别)

来源:互联网 发布:c语言混淆工具 编辑:程序博客网 时间:2024/05/17 23:44

java:网络编程(InetAddress,InetSocketAddress,URL,TCP(Socket与SeverSocket),TCP与UDP的区别)

 

InerAddress:

/**IP地址:在网络上唯一标示一台计算机
* 端口号:标示计算机上不同的应用程序
* java.net.InetAddress类:此类表示互联网协议 (IP) 地址。 
* 常用方法:
* getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
* getHostName() 获取此 IP地址的主机名。
* getHostAddress()返回 IP 地址字符串(以文本表现形式)。
* getLocalHost() 返回本地主机。
* getAllByName(String host) 在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。
*
*/

复制代码
public class TestInetAddress {    public static void main(String[] args) {        try {            //在给定主机名的情况下确定主机的 IP 地址。//            InetAddress inetAddress = InetAddress.getByName("P-PC");            InetAddress inetAddress = InetAddress.getLocalHost();//获取本地主机            System.out.println(inetAddress);            String hostName = inetAddress.getHostName();            System.out.println("主机名:"+hostName);            String ip = inetAddress.getHostAddress();            System.out.println("IP地址:"+ip);            //根据主机名或域名获取其IP地址            InetAddress[] ids = InetAddress.getAllByName("www.baidu.com");            for (InetAddress inetAddress2 : ids) {                System.out.println(inetAddress2);            }        } catch (UnknownHostException e) {            e.printStackTrace();        }            }}
复制代码

InetSocketAddress:

*java.net.InetSocketAddress类:此类实现 IP 套接字地址(IP 地址 + 端口号)。
*构造方法
*InetSocketAddress(InetAddress addr, int port)根据 IP 地址和端口号创建套接字地址。 
*InetSocketAddress(String hostname, int port) 根据主机名和端口号创建套接字地址。
*常用的方法:
* getAddress():获取 InetAddress。
* getPort() 获取端口号。
* toString() 构造此 InetSocketAddress 的字符串表示形式。(主机名/Ip:端口号)
* getHostName()获取 主机名。

复制代码
public class TestInetSocketAddress {    public static void main(String[] args) {//        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",3306);        try {            InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getLocalHost(), 3306);            System.out.println(socketAddress);            InetAddress inetAddress = socketAddress.getAddress();            System.out.println("主机信息:"+inetAddress);            int port = socketAddress.getPort();            System.out.println("端口号:"+port);            String hostName = socketAddress.getHostName();            System.out.println("主机名:"+hostName);        } catch (UnknownHostException e) {            e.printStackTrace();        }            }}
复制代码

URL:

*URL:统一资源定位符
*组成部分:协议,主机名或IP,端口号,资源路径
*java.net.URL类:代表一个统一资源定位符,它是指向互联网“资源”的指针
* 常用的构造方法
* URL(String spec) 根据 String 表示形式创建 URL 对象。
* URL(String protocol, String host, int port, String file) 根据指定 protocol、host、port 号和 file 创建 URL 对象。
* 常用的方法:
* getProtocol()获取此 URL 的协议名称。
* getHost()获取此 URL 的主机名(如果适用)。
* getPort() 获取此 URL 的端口号。
* getFile()获取此 URL 的文件名。
* getDefaultPort()获取与此 URL 关联协议的默认端口号。
* getPath()获取此 URL 的路径部分。
* ...

复制代码
public class TestURL {    public static void main(String[] args) {        try {            URL url = new URL("http://www.baidu.com/index.html#aa?cansu=bjsxt");            String protocol = url.getProtocol();            System.out.println("协议:"+protocol);            String host = url.getHost();            System.out.println("主机名:"+host);            int port = url.getPort();            System.out.println("端口号:"+port);            int defualtPort = url.getDefaultPort();            System.out.println("默认端口:"+defualtPort);            String file = url.getFile();            System.out.println("资源路径:"+file);            String path = url.getPath();            System.out.println("资源路径:"+path);        } catch (MalformedURLException e) {            e.printStackTrace();        }            }}
复制代码

URL类
* InputStream openStream() 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。

复制代码
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.MalformedURLException;import java.net.URL;public class WebSpider {    public static void main(String[] args) {        try {            URL url = new URL("https://channel.jd.com/men.html");            InputStream ips = url.openStream();            InputStreamReader isr = new InputStreamReader(ips);//将字节流转换为字符流            BufferedReader br = new BufferedReader(isr);            String str;            while((str=br.readLine())!=null){                System.out.println(str);            }            br.close();        } catch (MalformedURLException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}
复制代码

 Socket与SeverSocket信息的传递:

复制代码
import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;/**  * java.net.ServerSocket类:此类实现服务器套接字。服务器套接字等待请求通过网络传入 * 构造方法: * ServerSocket(int port)创建绑定到特定端口的服务器套接字。 *  * 常用方法: * accept() 侦听并接受到此套接字的连接。 * close() 关闭此套接字。 *  * 服务器端 */public class SimpleServer {    public static void main(String[] args) {        try {            System.out.println("------服务器端启动------");            //1.创建服务器端的套接字并指定端口            ServerSocket serverSocket = new ServerSocket(8888);            //2.侦听并接受到此套接字的连接。            Socket socket = serverSocket.accept();            //3.从套接字中获取一个输入流            InputStream ips = socket.getInputStream();            InputStreamReader isr = new InputStreamReader(ips);            char[] cs = new char[1024];            int len = isr.read(cs);            String message = new String(cs, 0, len);            System.out.println("客户端消息:"+message);            isr.close();            socket.close();            serverSocket.close();            System.out.println("服务器数据接收完毕!");        } catch (IOException e) {            e.printStackTrace();        }            }}
复制代码
复制代码
import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.Socket;import java.net.UnknownHostException;/** *java.net.Socket类:此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。  *构造方法: *Socket(InetAddress address, int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 *Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。 *常用方法: *getOutputStream()返回此套接字的输出流。 *getInputStream()  返回此套接字的输入流。 *close()关闭此套接字。 *客户端 */public class SimpleClient {    public static void main(String[] args) {        try {            System.out.println("-------客户端启动-------");            //1.创建一个套接字并将其连接到指定的IP地址的指定端口            Socket socket = new Socket("127.0.0.1",8888);            //2.获取套接字的输出流,用于输出数据            OutputStream ops = socket.getOutputStream();            OutputStreamWriter osw = new OutputStreamWriter(ops);            osw.write("你好!");            osw.flush();            osw.close();            socket.close();            System.out.println("客户端数据发送完毕!");        } catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }             }}
复制代码

 根据用户输入的账号密码,从服务器上判断是否正确并传递信息回来:

复制代码
import java.io.Serializable;/** * 如果要对该对象进行序列化,就必须实现Serializable接口 * 封装用户名和密码信息 */public class User implements Serializable{    private String userName;    private String password;    public User(){            }    public User(String userName,String password){        this.userName=userName;        this.password=password;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    }
复制代码
复制代码
import java.io.DataInputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectOutputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;import java.util.Scanner;/** * 客户端: * 1.获取用户名和密码 * 2.将用户名和密码封装成User对象 * 3.使用对象流将user对象发生到服务器端 * 4.读取服务器的响应消息 * 5.释放资源 */public class LoginClient {    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        //获取输入的用户名和密码        System.out.println("请输入用户名:");        String userName = input.next();        System.out.println("请输入密码:");        String password = input.next();        //将用户名和密码封装成User对象        User user = new User(userName,password);        try {            //创建Socket对象            Socket socket = new Socket("127.0.0.1",6666);            //获取输出流            OutputStream ops = socket.getOutputStream();            ObjectOutputStream oos = new ObjectOutputStream(ops);            //使用对象流将user对象发送到服务器端            oos.writeObject(user);            oos.flush();            //获取服务器端响应消息            InputStream ips = socket.getInputStream();            DataInputStream dis = new DataInputStream(ips);            String str = dis.readUTF();            System.out.println(str);            //释放资源            dis.close();            oos.close();            socket.close();        } catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }            }    }
复制代码
复制代码
import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;/** * 服务器端: * 1.获取客户端发送的user对象(封装了用户名和密码) * 2.判断用户名和密码是否合法 * 3.如果合法,向客户端发送"恭喜你,登陆成功!";否则向客户端发送"用户名或密码有误!" * 4.释放资源 */public class LoginServer {    public static void main(String[] args) {        try {            //1.获取客户端发送的用户名和密码信息            ServerSocket serverSocket = new ServerSocket(6666);            Socket socket = serverSocket.accept();            InputStream ips = socket.getInputStream();            ObjectInputStream ois = new ObjectInputStream(ips);            User user = (User)ois.readObject();            //2.判断用户名和密码是否正确            String message;            if("zzsxt".equals(user.getUserName())&&"zzsxt".equals(user.getPassword())){                message="恭喜你,登陆成功!";            }else{                message="用户名或密码有误!";            }            //3.创建输出流向客户端发送消息            OutputStream ops = socket.getOutputStream();            DataOutputStream dos = new DataOutputStream(ops);            dos.writeUTF(message);            dos.flush();            //4.释放资源            ois.close();            dos.close();            socket.close();            serverSocket.close();        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }            }}
复制代码

 方法2:

复制代码
/** * 服务器端: * 1.获取客户端发送的user对象(封装了用户名和密码) * 2.判断用户名和密码是否合法 * 3.如果合法,向客户端发送"恭喜你,登陆成功!";否则向客户端发送"用户名或密码有误!" * 4.释放资源 */public class LoginServer {    //用于保存用户名和密码的信息,利用用户名做键,利用密码做值    static Map<String,String> map = new HashMap<String,String>();    //初始化map    static{        map.put("zzsxt", "zzsxt");        map.put("bjsxt", "bjsxt");        map.put("whsxt", "whsxt");    }    static int count=0;//第几位访客        public static void main(String[] args) {        //1.获取客户端发送的用户名和密码信息        ServerSocket serverSocket=null;        Socket socket=null;        ObjectInputStream ois =null;        DataOutputStream dos=null;        try {            serverSocket = new ServerSocket(6666);            while(true){                socket = serverSocket.accept();                InputStream ips = socket.getInputStream();                ois = new ObjectInputStream(ips);                User user = (User)ois.readObject();                //2.判断用户名和密码是否正确                String userName = user.getUserName();//获取用户输入的用户名 aa                String password = user.getPassword();//获取用户输入的密码                String upass=map.get(userName);                String message;                if(upass!=null&&upass.equals(password)){                    count++;//计数                    message="恭喜你,登陆成功!您是第"+count+"位访客";                }else{                    message="用户名或密码有误!";                }                //3.创建输出流向客户端发送消息                OutputStream ops = socket.getOutputStream();                dos = new DataOutputStream(ops);                dos.writeUTF(message);                dos.flush();            }        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }finally{            try {                //4.释放资源                ois.close();                dos.close();                socket.close();                serverSocket.close();            } catch (IOException e) {                e.printStackTrace();            }        }            }}
复制代码

 方法3:转换为多线程交互

复制代码
import java.io.Serializable;/** * 如果要对该对象进行序列化,就必须实现Serializable接口 * 封装用户名和密码信息 */public class User implements Serializable{    private String userName;    private String password;    public User(){            }    public User(String userName,String password){        this.userName=userName;        this.password=password;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }        @Override    public String toString() {        return "User [userName=" + userName + ", password=" + password + "]";    }    }
复制代码
复制代码
public class LoginClient {    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        //获取输入的用户名和密码        System.out.println("请输入用户名:");        String userName = input.next();        System.out.println("请输入密码:");        String password = input.next();        //将用户名和密码封装成User对象        User user = new User(userName,password);        try {            //创建Socket对象            Socket socket = new Socket("127.0.0.1",6666);            //获取输出流            OutputStream ops = socket.getOutputStream();            ObjectOutputStream oos = new ObjectOutputStream(ops);            //使用对象流将user对象发送到服务器端            oos.writeObject(user);            oos.flush();            //获取服务器端响应消息            InputStream ips = socket.getInputStream();            DataInputStream dis = new DataInputStream(ips);            String str = dis.readUTF();            System.out.println(str);            //释放资源            dis.close();            oos.close();            socket.close();        } catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    }
复制代码
复制代码
import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.OutputStream;import java.net.Socket;import java.util.HashMap;import java.util.Map;/** * 用于处理客户端请求的线程 * @author Administrator * */public class ServerThread extends Thread{    private Socket socket;    //用于保存用户名和密码的信息,利用用户名做键,利用密码做值    static Map<String,String> map = new HashMap<String,String>();    //初始化map    static{        map.put("zzsxt", "zzsxt");        map.put("bjsxt", "bjsxt");        map.put("whsxt", "whsxt");    }    static int count=0;//第几位访客    //构造方法    public ServerThread(Socket socket){        this.socket=socket;    }    /**     * 处理客户端请求     */    @Override    public void run() {        ObjectInputStream ois =null;        DataOutputStream dos=null;        try {            InputStream ips = socket.getInputStream();            ois = new ObjectInputStream(ips);            User user = (User)ois.readObject();            //2.判断用户名和密码是否正确            String userName = user.getUserName();//获取用户输入的用户名 aa            String password = user.getPassword();//获取用户输入的密码            String upass=map.get(userName);            String message;            if(upass!=null&&upass.equals(password)){                count++;//计数                message="恭喜你,登陆成功!您是第"+count+"位访客";            }else{                message="用户名或密码有误!";            }            //3.创建输出流向客户端发送消息            OutputStream ops = socket.getOutputStream();            dos = new DataOutputStream(ops);            dos.writeUTF(message);            dos.flush();        } catch (IOException |ClassNotFoundException e) {            e.printStackTrace();        }finally{            try {                ois.close();                dos.close();                socket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}
复制代码
复制代码
/** * 面临的问题: *     当多个用户同时登陆时,只能排队等待。 * 解决方案:使用多线程进行解决,为每一个客户请求创建线程,为其提供服务。 *  * 服务器端: * 1.获取客户端发送的user对象(封装了用户名和密码) * 2.判断用户名和密码是否合法 * 3.如果合法,向客户端发送"恭喜你,登陆成功!";否则向客户端发送"用户名或密码有误!" * 4.释放资源 *  */public class LoginServer {        public static void main(String[] args) {        //1.获取客户端发送的用户名和密码信息        ServerSocket serverSocket=null;        try {            serverSocket = new ServerSocket(6666);            while(true){                Socket socket = serverSocket.accept();                //启动线程,处理用户请求                new ServerThread(socket).start();            }        } catch (IOException e) {            e.printStackTrace();        }finally{            try {                serverSocket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}
复制代码

 

 

TCP与UDP的区别:

1.TCP与UDP基本区别
  1.基于连接与无连接,TCP是面向连接,UDP是不面向连接;
  2.TCP要求系统资源较多效率低,UDP较占用资源少; 
  3.UDP程序结构较简单,TCP点到点的通信,UDP可以广播发送 ;
  4.流模式(TCP)与数据报模式(UDP); 
  5.TCP保证数据正确性,UDP可能丢包(发送不管对方是否准备好,接收方收到也无确认); 
  6.TCP保证数据顺序,UDP不保证 ;


  
2.UDP应用场景:
  1.面向数据报方式
  2.网络数据大多为短消息 
  3.拥有大量Client
  4.对数据安全性无特殊要求
  5.网络负担非常重,但对响应速度要求高
 
3.具体编程时的区别
   1.socket()的参数不同 
   2.UDP Server不需要调用listen和accept 
   3.UDP收发数据用sendto/recvfrom函数 
   4.TCP:地址信息在connect/accept时确定 
   5.UDP:在sendto/recvfrom函数中每次均 需指定地址信息 
   6.UDP:shutdown函数无效


阅读全文
0 0
原创粉丝点击