socketaddress java_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 地址所组成的数组。

*

*/

48304ba5e6f9fe08f3fa1abda7d326ab.png

public classTestInetAddress {public static voidmain(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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

InetSocketAddress:

*java.net.InetSocketAddress类:此类实现 IP 套接字地址(IP 地址 + 端口号)。

*构造方法

*InetSocketAddress(InetAddress addr, int port)根据 IP 地址和端口号创建套接字地址。

*InetSocketAddress(String hostname, int port) 根据主机名和端口号创建套接字地址。

*常用的方法:

*getAddress():获取 InetAddress。

*getPort() 获取端口号。

*toString() 构造此 InetSocketAddress 的字符串表示形式。(主机名/Ip:端口号)

*getHostName()获取 主机名。

48304ba5e6f9fe08f3fa1abda7d326ab.png

public classTestInetSocketAddress {public static voidmain(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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

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 的路径部分。

* ...

48304ba5e6f9fe08f3fa1abda7d326ab.png

public classTestURL {public static voidmain(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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

URL类

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

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 classWebSpider {public static voidmain(String[] args) {try{

URL url= new URL("");

InputStream ips=url.openStream();

InputStreamReader isr= new InputStreamReader(ips);//将字节流转换为字符流

BufferedReader br = newBufferedReader(isr);

String str;while((str=br.readLine())!=null){

System.out.println(str);

}

br.close();

}catch(MalformedURLException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

Socket与SeverSocket信息的传递:

48304ba5e6f9fe08f3fa1abda7d326ab.png

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 classSimpleServer {public static voidmain(String[] args) {try{

System.out.println("------服务器端启动------");//1.创建服务器端的套接字并指定端口

ServerSocket serverSocket = new ServerSocket(8888);//2.侦听并接受到此套接字的连接。

Socket socket =serverSocket.accept();//3.从套接字中获取一个输入流

InputStream ips =socket.getInputStream();

InputStreamReader isr= newInputStreamReader(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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

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 classSimpleClient {public static voidmain(String[] args) {try{

System.out.println("-------客户端启动-------");//1.创建一个套接字并将其连接到指定的IP地址的指定端口

Socket socket = new Socket("127.0.0.1",8888);//2.获取套接字的输出流,用于输出数据

OutputStream ops =socket.getOutputStream();

OutputStreamWriter osw= newOutputStreamWriter(ops);

osw.write("你好!");

osw.flush();

osw.close();

socket.close();

System.out.println("客户端数据发送完毕!");

}catch(UnknownHostException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

import java.io.Serializable;/**

* 如果要对该对象进行序列化,就必须实现Serializable接口

* 封装用户名和密码信息*/

public classUser implements Serializable{privateString userName;privateString password;publicUser(){

}

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;

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

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 classLoginClient {public static voidmain(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 = newUser(userName,password);try{//创建Socket对象

Socket socket = new Socket("127.0.0.1",6666);//获取输出流

OutputStream ops =socket.getOutputStream();

ObjectOutputStream oos= newObjectOutputStream(ops);//使用对象流将user对象发送到服务器端

oos.writeObject(user);

oos.flush();//获取服务器端响应消息

InputStream ips =socket.getInputStream();

DataInputStream dis= newDataInputStream(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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

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 classLoginServer {public static voidmain(String[] args) {try{//1.获取客户端发送的用户名和密码信息

ServerSocket serverSocket = new ServerSocket(6666);

Socket socket=serverSocket.accept();

InputStream ips=socket.getInputStream();

ObjectInputStream ois= newObjectInputStream(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= newDataOutputStream(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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

方法2:

48304ba5e6f9fe08f3fa1abda7d326ab.png

/**

* 服务器端:

* 1.获取客户端发送的user对象(封装了用户名和密码)

* 2.判断用户名和密码是否合法

* 3.如果合法,向客户端发送"恭喜你,登陆成功!";否则向客户端发送"用户名或密码有误!"

* 4.释放资源*/

public classLoginServer {//用于保存用户名和密码的信息,利用用户名做键,利用密码做值

static Map map = new HashMap();//初始化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();

}

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

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

48304ba5e6f9fe08f3fa1abda7d326ab.png

import java.io.Serializable;/**

* 如果要对该对象进行序列化,就必须实现Serializable接口

* 封装用户名和密码信息*/

public classUser implements Serializable{privateString userName;privateString password;publicUser(){

}

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 + "]";

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

public classLoginClient {public static voidmain(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 = newUser(userName,password);try{//创建Socket对象

Socket socket = new Socket("127.0.0.1",6666);//获取输出流

OutputStream ops =socket.getOutputStream();

ObjectOutputStream oos= newObjectOutputStream(ops);//使用对象流将user对象发送到服务器端

oos.writeObject(user);

oos.flush();//获取服务器端响应消息

InputStream ips =socket.getInputStream();

DataInputStream dis= newDataInputStream(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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

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 classServerThread extends Thread{privateSocket socket;//用于保存用户名和密码的信息,利用用户名做键,利用密码做值

static Map map = new HashMap();//初始化map

static{

map.put("zzsxt", "zzsxt");

map.put("bjsxt", "bjsxt");

map.put("whsxt", "whsxt");

}static int count=0;//第几位访客//构造方法

publicServerThread(Socket socket){this.socket=socket;

}/*

* 处理客户端请求*/@Overridepublic voidrun() {

ObjectInputStream ois=null;

DataOutputStream dos=null;try{

InputStream ips=socket.getInputStream();

ois= newObjectInputStream(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= newDataOutputStream(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();

}

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

/**

* 面临的问题:

* 当多个用户同时登陆时,只能排队等待。

* 解决方案:使用多线程进行解决,为每一个客户请求创建线程,为其提供服务。

*

* 服务器端:

* 1.获取客户端发送的user对象(封装了用户名和密码)

* 2.判断用户名和密码是否合法

* 3.如果合法,向客户端发送"恭喜你,登陆成功!";否则向客户端发送"用户名或密码有误!"

* 4.释放资源

**/

public classLoginServer {

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();

}

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值