Socket
1、简介:网络上运行的程序之间双向通信链路的终结点,是tcp和udp的基础
由ip地址和端口号组成
2、java提供的网络功能
1>InetAddress:用于标识网络上的硬件资源,相当于标识IP地址
2>URL:统一资源定位符 通过URL可以直接读取或写入网络上的数据
3>Sockets:使用TCP协议实现网络通信的Socket相关的类
4>Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信
3、InetAddress:
4、URL
2>使用URL读取网页内容
1、通过URL对象的openstream()方法可以得到指定资源的输入流
2、通过输入流可以读取、访问网络上的数据
5、Socket
1>基于TCP协议实现网络通信的类
客户端的Socket类
服务器端的ServerSocket类
2>Socket通信实现步骤(附 流程图)
创建ServerSocket和socket --> 打开连接到Socket的输入/输出流
--> 按照协议对Socket进行读/写操作 --> 关闭输入输出流、关闭Socket
服务端:
1、创建ServerSocket对象,绑定监听端口
2、通过accept()方法监听客户端请求
3、连接建立后,通过输入流读取客户端发送的请求信息
4、通过输出流向客户端发送响应信息
5、关闭相关资源
客户端:
1、创建Socket对象,指明需要连接的服务器的地址和端口号
2、连接建立后,通过输出流向服务器端发送请求信息
3、通过输入流获取服务器响应的信息
4、关闭相关资源
*注意:先运行服务器端再运行客户端
应用多线程来实现服务器与多客户端之间的通信
基本步骤:
1、服务器端创建ServerSocket,循环调用accept()等待客户端连接
2、客户端创建一个socket并请求和服务器端连接
3、服务器端接受客户端请求,创建socket与该客户建立专线连接
4、建立连接的两个socket在一个单独的线程上对话
5、服务器端继续等待新的连接
1、简介:网络上运行的程序之间双向通信链路的终结点,是tcp和udp的基础
由ip地址和端口号组成
2、java提供的网络功能
1>InetAddress:用于标识网络上的硬件资源,相当于标识IP地址
2>URL:统一资源定位符 通过URL可以直接读取或写入网络上的数据
3>Sockets:使用TCP协议实现网络通信的Socket相关的类
4>Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信
3、InetAddress:
package com.zy;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
public class Test01 {
public static void main(String[] args) throws
UnknownHostException {
//获取本机的InetAddress实例
InetAddress address = InetAddress.getLocalHost();
//主机名
System.out.println("主机名:" +address.getHostName());
//IP地址
System.out.println("IP地址:" +address.getHostAddress());
//获取字节数组形式的ip地址
byte[] bytes = address.getAddress();
System.out.println("字节数组形式的ip:" + Arrays.toString(bytes));
//直接输出InetAddress对象
System.out.println(address);
//获取本机外机器的InetAddress实例
//根据机器名获取InetAddress实例
//InetAddress address2 = InetAddress.getByName("PC201411181946");
//根据IP地址获取InetAddress实例
InetAddress address2 = address.getByName("169.254.6.168");
//主机名
System.out.println("主机名:" +address2.getHostName());
//IP地址
System.out.println("IP地址:" +address2.getHostAddress());
}
}
4、URL
1>基本用法:
package com.zy;
import java.net.MalformedURLException;
import java.net.URL;
/**
* URL常用方法
* @author Administrator
*
*/
public class Test02 {
public static void main(String[] args) {
try {
//创建一个URL实例
URL zy = new URL("http://www.imooc.com");
//根据一个URL创建一个新的URL,?后面跟携带的参数,#后面表示锚点
URL url = new URL(zy, "/index.html?username=tom#test");
//获取此url采用的协议
System.out.println("协议:" + url.getProtocol());
//获取此url的主机
System.out.println("主机:" + url.getHost());
//获取此url的端口号,如果未指定端口号,则使用默认的端口号,此时getPort()方法返回值为-1
System.out.println("端口:" + url.getPort()) ;
//获取此url的文件路径
System.out.println("文件路径" + url.getPath());
System.out.println("文件名:" + url.getFile());
System.out.println("相对路径:" + url.getRef());
System.out.println("查询字符串:" + url.getQuery());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
2>使用URL读取网页内容
1、通过URL对象的openstream()方法可以得到指定资源的输入流
2、通过输入流可以读取、访问网络上的数据
package com.zy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
/*
* 使用URL读取页面内容
*/
public class Test03 {
public static void main(String[] args) {
try {
//创建一个URL实例
URL url = new URL("http://www.baidu.com");
//通过URL的openStream方法获取URL对象所表示的资源的字节输入流
InputStream is= url.openStream();
//将字节输入流转换为字符输入流,转换时指定编码格式,防止乱码
InputStreamReader isr = new InputStreamReader(is,"utf-8");
//为字符输入流添加缓冲,提高读写效率
BufferedReader br = new BufferedReader(isr);
//读取数据,一次读取一行
String data = br.readLine();
while (data!=null) {//循环读取数据
System.out.println(data);//输出数据
data = br.readLine();
}
//关闭相关的资源
br.close();
isr.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5、Socket
1>基于TCP协议实现网络通信的类
客户端的Socket类
服务器端的ServerSocket类
2>Socket通信实现步骤(附 流程图)
创建ServerSocket和socket --> 打开连接到Socket的输入/输出流
--> 按照协议对Socket进行读/写操作 --> 关闭输入输出流、关闭Socket
服务端:
1、创建ServerSocket对象,绑定监听端口
2、通过accept()方法监听客户端请求
3、连接建立后,通过输入流读取客户端发送的请求信息
4、通过输出流向客户端发送响应信息
5、关闭相关资源
客户端:
1、创建Socket对象,指明需要连接的服务器的地址和端口号
2、连接建立后,通过输出流向服务器端发送请求信息
3、通过输入流获取服务器响应的信息
4、关闭相关资源
package com.zy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 基于TCP协议的Socket通信,实现用户登录
* 服务器端
*/
public class Server {
public static void main(String[] args) {
try {
// 1、创建一个服务器端socket,即ServerSocket,绑定指定的端口,并监听此端口
ServerSocket serverSocket = new ServerSocket(8777);
// 2、调用accept()方法开始监听,等待客户的连接
System.out.println("***服务器即将启动,等待客户端的连接***");
Socket socket = serverSocket.accept();
// 3、获取输入流,并获取客户端信息
InputStream is = socket.getInputStream();// 字节输入流
InputStreamReader isr = new InputStreamReader(is);// 将字节流转为字符流
BufferedReader br = new BufferedReader(isr);// 为输入流添加缓冲
String info = null;
while ((info = br.readLine()) != null) {
System.out.println("我是服务器,客户端说:" + info);
}
socket.shutdownInput();// 关闭输入流
// 4、获取输出流,向客户端发送请求
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("欢迎您!");
pw.flush();
// 5、关闭相关资源
pw.close();
os.close();
br.close();
isr.close();
is.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.zy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 客户端
*/
public class Client {
public static void main(String[] args) {
try {
// 1、创建客户端Socket,指定服务器地址和端口
Socket socket = new Socket("localhost", 8777);
// 2、获取输出流,向服务器端发送信息
OutputStream os = socket.getOutputStream();// 字节输出流
PrintWriter pw = new PrintWriter(os);// 将输出流包装为打印流
pw.write("用户名:admin;密码:123");
pw.flush();// 刷新缓存,向服务器端发送信息
socket.shutdownOutput();// 关闭输出流
// 3、获取输入流,并读取服务器响应信息
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while ((info = br.readLine()) != null) {
System.out.println("我是客户端,服务器说:" + info);
}
// 4.关闭资源
is.close();
br.close();
pw.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
*注意:先运行服务器端再运行客户端
3>上述只实现了一个服务器和一个客户端之间的通信,如果有多个客户端呢?
应用多线程来实现服务器与多客户端之间的通信
基本步骤:
1、服务器端创建ServerSocket,循环调用accept()等待客户端连接
2、客户端创建一个socket并请求和服务器端连接
3、服务器端接受客户端请求,创建socket与该客户建立专线连接
4、建立连接的两个socket在一个单独的线程上对话
5、服务器端继续等待新的连接
package com.zy;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 基于TCP协议的Socket通信,实现用户登录
* 服务器端
*/
public class Server {
public static void main(String[] args) {
try {
// 1、创建一个服务器端socket,即ServerSocket,绑定指定的端口,并监听此端口
ServerSocket serverSocket = new ServerSocket(8777);
Socket socket = null;
//记录客户端的数量
int count = 0;
System.out.println("***服务器即将启动,等待客户端的连接***");
//循环监听等待客户端连接
while(true){
//调用accept()方法开始监听,等待客户的连接
socket = serverSocket.accept();
//创建一个新的线程
ServerThread serverThread = new ServerThread(socket);
//启动线程
serverThread.start();
count++;//统计客户端的数量
System.out.println("客户端的数量为:"+count);
InetAddress address = socket.getInetAddress();//获取客户端的ip地址
System.out.println("当前客户端的IP:"+address.getHostAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.zy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
/*
* 服务器线程处理类
*/
public class ServerThread extends Thread {
// 和线程相关的Socket
Socket socket = null;
// 每次创建ServerThread线程时就会初始化和本线程相关的socket
public ServerThread(Socket socket) {
this.socket = socket;
}
// 线程执行操作,响应客户端请求(重写父类run方法)
public void run() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
// 3、获取输入流,并获取客户端信息
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String info = null;
while ((info = br.readLine()) != null) {
System.out.println("我是服务器,客户端说:" + info);
}
socket.shutdownInput();// 关闭输入流
// 4、获取输出流,向客户端发送请求
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("欢迎您!");
pw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 5、关闭相关资源
if (pw != null)
pw.close();
if (os != null)
os.close();
if (br != null)
br.close();
if (isr != null)
isr.close();
if (is != null)
is.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}