Java网络编程---Socket
来源:互联网 发布:淘宝分销货源平台 编辑:程序博客网 时间:2024/05/18 23:26
java网络编程
java中实现网络编程用到的套接字是Socket,在引入Socket的时候先来了解一下网络通信协议。
网络通信协议:
计算机网络中实现通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。
网络通信协议的分层:
OSI参考模型:
- 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
TCP/IP参考模型:
- 应用层(HTTP、FTP、SMTP、DNS)
- 传输层(TCP、UDP)
- 网络层(IP、ARP、ICMP)
- 链路层(各种网络接口)
TCP
- 含义:是一种面向连接的、可靠的、基于字节流的运输层通信协议。
- 特点:
- 1、面向连接
- 2、点到点通信
- 3、高可靠性
- 4、占用系统资源多、效率低
UDP
- 含义:一种无连接的传输协议,提供面向事物的简单不可靠信息传送服务。
- 特点:
- 1、非面向连接,传输不可靠,数据可能丢失。
- 2、发送数据时也不管对方是否准备好,接收方也得不到确认。
- 3、可以广播发送
- 4、非常简单的协议,开销小。
InetAddress类:
用于封装计算机IP地址,但没有端口。
//使用getLocalHost方法创建InetAddress对象 InetAddress addr = InetAddress.getLocalHost(); System.out.println(addr.getHostAddress()); //返回IP地址 System.out.println(addr.getHostName()); //输出计算机名 //根据域名得到InetAddress对象 addr = InetAddress.getByName(“www.163.com”); System.out.println(addr.getHostAddress()); //返回 163服务器的ip:61.135.253.15 System.out.println(addr.getHostName()); //输出:www.163.com //根据ip得到InetAddress对象 addr = InetAddress.getByName(“61.135.253.15”); System.out.println(addr.getHostAddress()); //返回 163服务器的ip:61.135.253.15 System.out.println(addr.getHostName()); //输出ip而不是域名。如果这个IP地 址不存在或DNS服务器不允许进行IP地址和域名的映射,getHostName方法就直接返回这个IP地址。
InetSocketAddress类
用于socket通信,包含端口。
//包含端口 InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080); InetSocketAddress socketAddress2 = new InetSocketAddress(“localhost”,9000); System.out.println(socketAddress.getHostName()); System.out.println(socketAddress2.getAddress());
套接字Socket
在客户/服务器通信模式中,客户端需要主动建立与服务器连接的Socket,服务器端收到客户端的连接请求,也会创建与客户端连接的Socket。Socket可以看做是通信连接两端的收发器,客户端和服务店都通过Socket来收发数据。
Socket通信实现步骤:
- 1、创建ServerSocket和Socket
- 2、打开连接Socket的输入/输出流
- 3、按照协议(TCP/UDP)对Socket进行读写操作
- 4、关闭输入、输出流,关闭Socket
Server服务端:
- a、创建ServerSocket对象,同时绑定监听端口
- b、通过accept()方法监听客户端的请求
- c、建立连接后,通过输入流读取客户端发送的请求信息
- d、通过输出流向客户端发送响应信息
- e、关闭相应资源
TCP编程:
package com.net.socket; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** * socket服务端(接受数据) * * @author admin * */ public class ServiceSocket implements Runnable { Thread thread; public ServiceSocket() { thread = new Thread(this); thread.start(); } @Override public void run() { try { // TODO Auto-generated method stub System.out.println("服务器已经启动"); // 1.创建ServerSocket对象 ServerSocket server = new ServerSocket(8888); // 2.通过accept();方法,开启端口监听 Socket client = server.accept(); // 3.创建输入流 InputStream is = client.getInputStream(); DataInputStream dis = new DataInputStream(is); // 4.接受数据 System.out.println(client.getInetAddress() + "收到"); String read = dis.readUTF(); System.out.println(read); // 5.关闭流 dis.close(); is.close(); // 6.关闭Socket client.close(); server.close(); } catch (Exception e) { // TODO: handle exception } } }
2、Client客户端:
- a、创建Socket对象,指明需要连接的服务器的地址和端口号
- b、建立连接后,通过输出流向服务器端发送请求信息
- c、通过输入流获取服务器的响应信息
d、关闭相应资源
package com.bjsxt.socket;import java.io.DataOutputStream;import java.io.IOException;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;/** * socket客户端(发送数据) * * @author admin * */public class ClientSocket {public static void main(String[] args) throws UnknownHostException, IOException { System.out.println("客户端已经启动"); // 1.创建socket对象 Socket client = new Socket("192.168.88.222",6666); // 2.向服务器发送数据(创建输出流对象) OutputStream os = client.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); // 3.写数据 dos.writeUTF("IP地址"+client.getInetAddress().getHostAddress()+"发送消息:HelloWorld"); // 4.断开输出流 os.close(); dos.close(); // 5.关闭socket client.close(); }}
TCP通信功能总结:
- 服务器创建ServerSocket,在指定端口监听并并处理请求;
ServletSocket通过accept() 接收用户请求并返回对应的Socket,否则一种处于监听等待状态,线程也被阻塞
客户端创建Socket,需要指定服务器的ip和端口号,向服务器发送和接收响应客户端发送数据需要输出流(写),客户端获取反馈数据需要输入流(读)
- 服务端反馈数据需要输出流(写),服务端获取请求数据需要输入流(读)
一旦使用ServerSocket和Socket建立了网络连接后,网络通信和普通IO流操作并没有太大区别
网络通信输出流建议使用DataOutputStream和ObjectOutputStream,与平台无关,输入流相应使用 DataIntputStream和ObjectInputStream如果是字符串通信也可以使用BufferedReader和PrintWriter,简单方便
UDP编程:
- 1.UDP没有严格的客户端和服务器端区分,双方是平等的。实现代码也是类似的。
- 2.主动发起请求的称为客户端,被动接收请求的称为服务器端。
- 3.UDP编程和IO流没有关系
- 4.UDP编程的核心类 DatagramSocket:发送或者接收数据报包,DatagramPacket数据报包
代码实例:
public class AskCliect { //客户端类 public static void main(String[] args) throws IOException { // 创建DatagramSocket,用来发送或者接收数据 DatagramSocket socket = new DatagramSocket(29999); // 接收数据的端口 Scanner sc = new Scanner(System.in); while (true) {//定义循环和Scanner 是为了从键盘循环输入发送的内容。 String str = sc.nextLine(); byte[] buf = str.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.88.123"), 20001); socket.send(packet); // 发送数据 byte[] buf1 = new byte[1024]; // DatagramPacket服务器的接收数据的 DatagramPacket packet1 = new DatagramPacket(buf1, buf1.length); socket.receive(packet1); // 接收数据 System.out.println("收到的数据:" + new String(packet1.getData())); if("bye".equals(str)){//输入bye退出 break; } } // 关闭资源 socket.close(); }}
.
public class AskServer { public static void main(String[] args) throws IOException { // 创建DatagramSocket,用来发送或者接收数据 DatagramSocket socket = new DatagramSocket(20001); // 端口接收数据的 Scanner sc = new Scanner(System.in); while (true) {//同样为了循环接收数据并且回传消息,实现简单的聊天功能 byte[] buf = new byte[1024]; // DatagramPacket服务器的接收数据的 DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); // 接收数据 String info=new String(packet.getData()); System.out.println("收到的数据:" + info); String str = sc.nextLine(); byte[] buf1 = str.getBytes(); DatagramPacket packet1 = new DatagramPacket(buf1, buf1.length, packet.getAddress(), packet.getPort()); socket.send(packet1); // 发送数据 if("bye".equals(info)){ //输入bye退出 break; } } socket.close(); }}
Socket类提供了3个状态测试方法:
- 1、isClosed():如果Socket已经连接到远程主机,并且还没有关闭,则返回true
- 2、isConnected():如果Socket曾经连接到远程主机,则返回true
- 3、isBound():如果Socket已经与一个本地端口绑定,则返回true
如果要判断一个Socket对象当前是否处于连接状态,可以采用以下方式:
boolean isConnected = socket.isConnected()&&!socket.isClosed();
关闭Socket
1、有的时候,可能仅仅希望关闭输出流或输入流之一。此时可以采用Socket类提供的半关闭方法:
shutdownInput():关闭输入流。
shutdownOutput(): 关闭输出流。
2、注意:先后调用Socket的shutdownInput()和shutdownOutput()方法,仅仅关闭了输入流和输出流,并不等价于调用Socket的close()方法。在通信结束后,仍然要调用Socket的close()方法,因为只有该方法才会释放Socket占用的资源,比如占用的本地端口等。
3 Socket类还提供了两个状态测试方法,用来判断输入流和输出流是否关闭:
public boolean isInputShutdown();
public boolean isOutputShutdown();
—————————————————————————————————————————
笔者知识点有限,如有不足或者错误的地方,还请多多指正。【抱拳】
- Java网络编程--Socket
- java 网络编程socket
- Java网络编程-Socket
- Java Socket网络编程
- Java Socket网络编程
- Java Socket网络编程
- java网络编程socket
- java网络编程socket
- Java Socket网络编程
- java Socket网络编程
- java Socket网络编程
- java socket网络编程
- Java Socket网络编程
- java Socket网络编程
- Socket--java网络编程
- java socket网络编程
- java网络socket编程
- java socket网络编程
- Redis数据结构和内部编码--集合(Set)
- 人工智能与推荐系统
- 使用C++11特性对duilib窗口类封装---CEasyBox
- 把编程当做事业
- mysql5.7.18版本免安装配置教程
- Java网络编程---Socket
- linux centos SSH 连接超时,延长连接时间
- C++笔记之【Webservice流程整理】的那些事
- DirectDiskUrlFilter
- python:类与oop->装饰器的使用
- 最后的证明:8.15
- Linux Centos7 安装 nginx
- yii2整合yar实现RPC
- delphi自带md5的使用