Java Socket应用

来源:互联网 发布:淘宝上什么祛痘产品好 编辑:程序博客网 时间:2024/05/20 08:44

Socket编程

1.InetAddress类
2.URL
3.TCP编程
4.UDP编程
详情参考相关JDK的API文档

1.InetAddress类

InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址
public class Test {public static void main(String[] args) throws UnknownHostException {//获取本机的InetAddress实例InetAddress address=InetAddress.getLocalHost();System.out.println("计算机名"+address.getHostName());System.out.println("IP地址"+address.getHostAddress());byte[] bytes=address.getAddress();  //获取字节数组形式的IP地址System.out.println("字节数组形式IP地址"+Arrays.toString(bytes));System.out.println(address);//根据机器名获取InetAddress实例InetAddress address2=InetAddress.getByName("DESKTOP-USC18G4");System.out.println("计算机名"+address2.getHostName());System.out.println("IP地址"+address2.getHostAddress());//根据IP地址获取InetAddress实例InetAddress address3=InetAddress.getByName("192.168.73.1");System.out.println("计算机名"+address3.getHostName());System.out.println("IP地址"+address3.getHostAddress());}}

结果:
计算机名DESKTOP-USC18G4IP地址192.168.73.1字节数组形式IP地址[-64, -88, 73, 1]DESKTOP-USC18G4/192.168.73.1计算机名DESKTOP-USC18G4IP地址192.168.73.1计算机名DESKTOP-USC18G4IP地址192.168.73.1



2.URL

URL统一资源定位符,表示Internet上某一资源的地址,由协议名和资源名组成,中间用冒号隔开
在java.net包中,提供了URL类来表示URL

基本方法:
public class Test02 {public static void main(String[] args) {try {URL baidu=new URL("http://www.baidu.com");URL url=new URL(baidu,"/index.html?name=we#test");//#后面表示锚点System.out.println("协议:"+url.getProtocol());System.out.println("主机"+url.getHost());//若未指定端口号,则使用默认端口号-1System.out.println("端口"+url.getPort());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();}}}

结果:
协议:http主机www.baidu.com端口-1文件路径/index.html文件名/index.html?name=we相对路径test查询字符串name=we



使用URL读取网页内容

通过URL对象的openStream方法可以得到指定资源的输入流
通过输入流可以读取或访问网络上的资源

public class Test03 {public static void main(String[] args) {try {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 (Exception e) {e.printStackTrace();}}}
结果:
<!DOCTYPE html><!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta ht........................................



Socket通信

基于TCP协议实现网络通信有两个Socket类:
客户端的Socket类
服务器端的ServerSocket类


Socket通信模型





Socket实现步骤

1.创建ServerSocket和Socket
2.打开连接到Socket的输入/输出流
3.按照协议对Socket进行读/写操作
4.关闭输入输出流、关闭Socket


服务端具体步骤:

1.创建ServerSocket对象,绑定监听端口
2.通过accept()方法监听客户端请求
3.连接建立后,通过输入流读取客户端发送的请求信息
4.通过输出流向客户端发送响应信息
5.关闭相关资源

public class Server {//基于TCP协议的Socket通信,实现用户登录//服务器端public static void main(String[] args) throws Exception {//1.创建ServerSocket对象,绑定监听端口ServerSocket serversocket=new ServerSocket(8888);//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 pe=new PrintWriter(os);pe.write("欢迎你!");pe.flush();  //刷新缓存,发送//5.关闭相关资源pe.close();os.close();br.close();isr.close();is.close();socket.close();serversocket.close();}}

结果:
*****服务器即将启动,等待客户端连接*****我是服务器,客户端说:用户名:admin,密码:123


客户端具体步骤:

1.创建Socket对象,指明需要连接的服务器的地址和端口号
2.连接建立后,通过输出流向服务器端发送请求信息
3.通过输入流获取服务器端响应的信息
4.关闭相关资源


public class Client {//客户端public static void main(String[] args) throws UnknownHostException, IOException {//创建客户端Socket,指定服务器地址和端口Socket socket=new Socket("localhost",8888);//获取输出流,向服务器端发送消息OutputStream out=socket.getOutputStream();PrintWriter pe=new PrintWriter(out);pe.write("用户名:admin,密码:123");pe.flush();  //刷新缓存,发送socket.shutdownOutput();//获取输入流,读取服务器端的响应信息InputStream is=socket.getInputStream();BufferedReader br=new BufferedReader(new InputStreamReader(is));String info=null;while((info=br.readLine())!=null){System.out.println("我是客户端,服务器端说:"+info);}//关闭相关资源br.close();is.close();pe.close();out.close();socket.close();}}

结果:
我是客户端,服务器端说:欢迎你!




多线程实现多客户端通信

基本步骤:
1.服务器端创建SeverSocket,循环调用accept(),等待客户端连接
2.客户端创建一个Socket并请求和服务器端连接
3.服务器接收请求,创建Socket与该客户建立专线连接
4.建立的两个socket在一个单独的线程上对话
5.服务器端继续等待新连接



ServerThread类:

//服务器线程处理类public class ServerThread extends Thread {//和本线程相关的socketSocket socket=null;public ServerThread(Socket socket) {this.socket = socket;}//响应客户端请求@Overridepublic void run() {//连接建立后,通过输入流读取客户端发送的请求信息InputStream is=null;InputStreamReader isr=null;BufferedReader br=null;OutputStream os=null;PrintWriter pe=null;try {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();//关闭输入流//获取输出流,响应客户端os=socket.getOutputStream();pe=new PrintWriter(os);pe.write("欢迎你!");pe.flush();  //刷新缓存,发送} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{//关闭相关资源try {if(pe!=null)pe.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();}}}}



Server类:

public class Server {//基于TCP协议的Socket通信,实现用户登录//服务器端public static void main(String[] args) throws Exception {//创建ServerSocket对象,绑定监听端口ServerSocket serversocket=new ServerSocket(8888);Socket socket=null;int count=0;  //记录客户端的数量System.out.println("*****服务器即将启动,等待客户端连接*****");while(true){//通过accept()方法监听客户端请求socket=serversocket.accept();//创建一个新线程ServerThread st=new ServerThread(socket);st.start();count++;System.out.print("客户端的数量:"+count+" ");InetAddress address=socket.getInetAddress();System.out.println("当前客户端的IP地址:"+address.getHostAddress());}}}




Client类:

public class Client {//客户端public static void main(String[] args) throws UnknownHostException, IOException {//创建客户端Socket,指定服务器地址和端口Socket socket=new Socket("localhost",8888);//获取输出流,向服务器端发送消息OutputStream out=socket.getOutputStream();PrintWriter pe=new PrintWriter(out);pe.write("用户名:Tony,密码:123");pe.flush();  //刷新缓存,发送socket.shutdownOutput();//获取输入流,读取服务器端的响应信息InputStream is=socket.getInputStream();BufferedReader br=new BufferedReader(new InputStreamReader(is));String info=null;while((info=br.readLine())!=null){System.out.println("我是客户端,服务器端说:"+info);}//关闭相关资源br.close();is.close();pe.close();out.close();socket.close();}}

运行结果:          先启动Server,再启动多个Client,即可看到如下信息
*****服务器即将启动,等待客户端连接*****客户端的数量:1 当前客户端的IP地址:127.0.0.1我是服务器,客户端说:用户名:admin,密码:123客户端的数量:2 当前客户端的IP地址:127.0.0.1我是服务器,客户端说:用户名:Tony,密码:123







UDP编程

进行数据传输时,首先需要将传输的数据定义成数据报(Datagram),在数据报中指明数据所要到达的socket(主机地址和端口),发送数据报

相关操作类:
DatagramPacket:表示数据报包
DatagramSocket:进行端到端通信的类



服务端实现步骤:

1.创建DatagramSocket,指定端口号
2.创建DatagramPacket
3.接收客户端发送的数据信息
4.读取数据

public class UDPServer {public static void main(String[] args) throws IOException {//创建服务器端DatagramSocket,指定端口DatagramSocket socket=new DatagramSocket(8800);//创建数据报,用于接收客户端发送的数据byte[] data=new byte[1024];  //指定接收的数据包的大小DatagramPacket packet=new DatagramPacket(data,data.length);//接收客户端发送的数据System.out.println("******服务端启动,等待客户端发送数据*****");socket.receive(packet);  //此方法在接收到数据报之前会一直阻塞//读取数据String info=new String(data,0,packet.getLength());System.out.println("我是服务器,客户端说:"+info);//响应客户端//得到客户端的IP,端口InetAddress address=packet.getAddress();int port=packet.getPort();byte[] data2="欢迎你".getBytes();DatagramPacket packet2=new DatagramPacket(data2,data2.length,address,port);socket.send(packet2);//关闭资源socket.close();}}

结果:
******服务端启动,等待客户端发送数据*****我是服务器,客户端说:用户名:admin,密码:123


客户端实现步骤:

1.定义发送信息
2.创建DatagramPacket,包含要发送的信息
3.创建DatagramSocket
4.发送数据


public class UDPClient {//客户端public static void main(String[] args) throws Exception {InetAddress address=InetAddress.getByName("localhost");int port=8800;byte[] data="用户名:admin,密码:123".getBytes();DatagramPacket packet=new DatagramPacket(data,data.length,address,port);DatagramSocket socket=new DatagramSocket();socket.send(packet);//接收服务器响应数据byte[] data2=new byte[1024];  DatagramPacket packet2=new DatagramPacket(data2,data2.length);socket.receive(packet2);  //此方法在接收到数据报之前会一直阻塞//读取数据String info=new String(data2,0,packet2.getLength());System.out.println("我是客户端,服务器说:"+info);//关闭资源socket.close();}}

结果:
我是客户端,服务器说:欢迎你