一、Socket基础:
协议:A电脑给B电脑通信说话,使用的语言就是协议。
端口号:电脑可以运行多个程序,而端口号就是区分不同程序的。端口号是程序的唯一标识。
常用端口号: hhttp:80 ftp:21 telnet:23 mysql:3306
Socket:IP地址和端口好组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础。
正对网络通信的不同层次,Java提供的网络功能有四大类:
①、InetAddress:用于标识网络上能够的硬件资源
②、URL:统一资源定位符,通过URL可以直接读取或写入网络上的数据。
③、Sockets:使用TCP协议实现网络通信的Socket相关的类。
④、Datagram(通信报):使用UDP协议,将数据保存在数据报中,通过网络进行通信。
二、InetAddress类:
作用:通过InetAddress实例获取机器名和IP地址。
如:
// 获取本机的InetAddress实例
InetAddress address = InetAddress.getLocalHost();
// 根据 机器名/IP地址 获取InetAddress实例
// InetAddress address2 = InetAddress.getByName("PC-201707021130");
// InetAddress address2 = InetAddress.getByName("192.168.23.2");
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("计算机名/IP地址:" + address);
三、URL:
URL由两部分组成:协议名称和资源名称,中间用冒号隔开。
①作用:获取 端口号、协议、机器名、文件路劲
如:
// 创建一个URL实例
URL imooc = new URL("http://www.imooc.com";);
URL url = new URL(imooc, "/index.html?username=tom#test");// #表示锚点
System.out.println("协议:" + url.getProtocol());
System.out.println("主机:" + url.getHost());
// 如果未指定端口号,则使用协议的默认端口号
System.err.println("端口号:" + url.getPort());
System.out.println("文件路径:" + url.getPath());
System.out.println("文件名:" + url.getFile());
System.out.println("相对路劲:" + url.getRef());
System.out.println("查询字符串:" + url.getQuery());
②、通过URl对象的openStream()方法可以得到指定资源的输入流,通过输入流可以读取、访问网络上的数据。
如;获取百度主页信息
try {
// 创建一个URL实例
URL url = new URL("http://www/baidu.com";);
// 通过URL的openStream方法获取URL对象表示的资源字节输入流
InputStream openStream = url.openStream();
// 将字节输入流转换为字符输入流
InputStreamReader isr = new InputStreamReader(openStream,"UTF-8");
// 添加缓存
BufferedReader bt = new BufferedReader(isr);
String data = bt.readLine();
while (data != null) {
System.out.println(data);
data = bt.readLine();
}
bt.close();
isr.close();
openStream.close();
} catch (IOException e) {
e.printStackTrace();
}
四、Socket通信模型:
TCP协议是面向连接、有序的、以字节流的方式发送数据
基于TCP实习网络通信的类:
客服端Socket类
服务端的ServerSocket类
基本实现:
服务器端 实现步骤:
1、创建ServerSocket对象,绑定监听端口
2、通过accept()方法监听客户端请求
3、连接建立后,通过输入流读取客户端发送的请求信息
4、通过输入流像客户端发送响应信息
5、关闭输入输出流,Socket
客户端 实现步骤:
1、创建Socket对象,指明需要链接的服务器的地址和端口号
2、连接建立后,通过输出流向服务器端发送请求信息
3、通过输入流获取服务器响应的信息
4、关闭输入输出流,Socket
应用多线程来实现服务器与客户端之间的通信:
1、服务器端创建ServerSocket,循环调用accept()方法等待客户端连接
2、客户端创建一个socket并请求和服务器端连接
3、服务器端接受客户端请求,创建socket与该客户建立专线连接
4、建立连接的两个socket在一个单独的线程上对话
5、服务器继续等待新的连接
具体代码:有 Cliect类,Server类,ServerThread类 (复制、粘贴到eclipse,即可运行)
Server:
package com.imoc.socket;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
importjava.net.Socket;
public class Server {
public static void main(String[] args) {
try {
Socket socket = null;
int count=0;//记录客户端数量
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("***服务器即将启动,等待客户端的连接***");
while (true) {
socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
count++;
System.out.println("客户端的数量:"+count);
InetAddress Address = socket.getInetAddress() ;
System.out.println("客户端的IP地址:"+Address.getHostAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.imoc.socket;
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;
public ServerThread(Socket socket) {
this.socket = socket;
}
// 线程执行的操作,响应客户端的请求
@Override
public void run() {
InputStream is=null;
BufferedReader bf=null;
OutputStream os=null;
PrintWriter pw=null;
try {
is = socket.getInputStream();
bf = new BufferedReader(new InputStreamReader(is));
String info = null;
while ((info = bf.readLine()) != null) {
System.out.println("我是服务器,客户端说:" + info);
}
socket.shutdownInput();// 关闭输出输入流
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("欢迎您");
pw.flush();
socket.shutdownOutput();// 关闭输出流
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (pw != null) {
pw.close();
}
if (os != null) {
os.close();
}
if (bf != null) {
bf.close();
}
if (is != null) {
is.close();
}
if (socket!=null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Cliect:
package com.imoc.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
importjava.net.Socket;
public class Cliect {
public static void main(String[] args) {
try {
Socket socket = null;
OutputStream os = null;
PrintWriter pw = null;
InputStream is = null;
BufferedReader bf = null;
socket = new Socket("localhost", 8888);
System.out.println("我是客户端");
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("用户名:tom;密码:456");
pw.flush();
socket.shutdownOutput();// 关闭输入流
is = socket.getInputStream();
bf = new BufferedReader(new InputStreamReader(is));
String data = null;
while ((data = bf.readLine()) != null) {
System.out.println("我是客户端,服务器说:" + data);
}
socket.shutdownInput();// 关闭输出流
bf.close();
is.close();
pw.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}