InerAddress:
/**IP地址:在网络上唯一标示一台计算机
* 端口号:标示计算机上不同的应用程序
* java.net.InetAddress类:此类表示互联网协议 (IP) 地址。
* 常用方法:
* getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
*getHostName() 获取此 IP地址的主机名。
*getHostAddress()返回 IP 地址字符串(以文本表现形式)。
*getLocalHost() 返回本地主机。
*getAllByName(String host) 在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。
*
*/
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();
}
}
}
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 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();
}
}
}
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 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();
}
}
}
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 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();
}
}
}
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 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();
}
}
}
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();
}
}
}
根据用户输入的账号密码,从服务器上判断是否正确并传递信息回来:
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;
}
}
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();
}
}
}
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();
}
}
}
方法2:
/**
* 服务器端:
* 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();
}
}
}
}
方法3:转换为多线程交互
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 + "]";
}
}
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();
}
}
}
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();
}
}
}
}
/**
* 面临的问题:
* 当多个用户同时登陆时,只能排队等待。
* 解决方案:使用多线程进行解决,为每一个客户请求创建线程,为其提供服务。
*
* 服务器端:
* 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();
}
}
}
}
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函数无效