Socket 翻译过来为“套接字”,英文含义为插座,先看下百科上对套接字的定义: TCP用主机的IP地址加上主机的端口号作为TCP连接的端点,这种端点就叫做套接字(Socket)或插口。套接字用(IP地址:端口号)表示,它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
感觉说了太多废话,简单点就是socket是在应用层和传输层的一个抽象层,它把对传输层的复杂操作抽象成几个简单的接口,应用层通过调用实现进程中的通信。看下图吧:
对于网络通信了解有限的童鞋不必深究,先会用再说
简单讲就是假设一个Socket客户端,一个Socket服务端,开启Socket服务端之后,服务端会进入循环监听状态等待客户端的连接,客户端发送请求后,继而连接成功后也就打通了数据传输通道。
主要还是直接写代码测试,最后再去进一步理解:
服务端:
package Testdemo;
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.util.Date;
public class ServerThread extends Thread{
// 和本线程相关的Socket
Socket socket = null;
public ServerThread(Socket socket) {
this.socket = socket;
}
//线程执行的操作,响应客户端的请求
public void run(){
InputStream is=null;
InputStreamReader isr=null;
BufferedReader br=null;
OutputStream os=null;
PrintWriter pw=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();
pw = new PrintWriter(os);
pw.write("欢迎您!client: "+socket.getLocalSocketAddress()+",时间 :"+new Date());
pw.flush();//调用flush()方法将缓冲输出
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭资源
try {
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();
}
}
}
}
客户端:
package Testdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientThread extends Thread{
String info = null;
public ClientThread(String info){
this.info = info;
}
public void run(){
try {
Socket socket = new Socket("127.0.0.1", 8989);
OutputStream os = socket.getOutputStream();
os.write(info.getBytes());
os.flush();
socket.shutdownOutput();
// 接受服务器返回的消息
InputStream inputStream = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
System.out.println("服务器返回消息说:"+br.readLine());
os.close();
br.close();
inputStream.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试入口:
package Testdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import org.junit.Test;
public class TestSocket {
@Test
public void testClient(){
Socket client = null;
OutputStream outputStream = null;
OutputStreamWriter ow = null;
int i =1;
for(;i<3;i++){
try {
// 创建一个socket对象,并建立网络连接(可以使用以下三种方式任何一种)
client = new Socket("localhost",8989);
// client = new Socket("127.0.0.1",8989);
// client = new Socket(InetAddress.getByName("127.0.0.1"),8989);
System.out.println("client socket "+client.hashCode()+",建立了socket实例时间:"+new Date());
//设置等待
client.setSoTimeout(15000);
//获取远程请求地址和端口
InetAddress inetAddress = client.getInetAddress();
int port = client.getPort();
String hostAddress = inetAddress.getHostAddress();
String hostName = inetAddress.getHostName();
InetAddress localHost = inetAddress.getLocalHost();
System.out.println("远程主机 :"+inetAddress+",远程端口:"+port+",远程hostAddress:"+hostAddress+",远程hostName:"+hostName);
//获取发起的地址和端口
InetAddress localAddress = client.getLocalAddress();
int localPort = client.getLocalPort();
String hostAddress2 = localAddress.getHostAddress();
String hostName2 = localAddress.getHostName();
System.out.println("本地主机 :"+localAddress+",本地端口 :"+localPort+",本地hostAddress:"+hostAddress2+",本地hostName:"+hostName2);
//打开输出流,要发送消息
outputStream = client.getOutputStream();
ow = new OutputStreamWriter(outputStream);
ow.write("I'm jane,please take care!");
ow.flush();
// 关掉输出流,说明客户端已经写完了
client.shutdownOutput();
//获取输入流,接收服务器返回的消息
InputStream inputStream = client.getInputStream();
InputStream is=inputStream;
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String info=null;
while((info=br.readLine())!=null){
System.out.println("我是客户端,服务器说:"+info);
}
}catch (IOException e) {
e.printStackTrace();
}finally{
try {
outputStream.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void testClientThread(){
while(true){
InputStream is=null;
InputStreamReader isr=null;
BufferedReader br=null;
Socket socket = null;
OutputStream outputStream = null;
try {
is = System.in;
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String info=null;
while((info=br.readLine())!=null){//循环读取客户端的信息
System.out.println("当前输入的信息是:"+info);
try {
socket = new Socket("127.0.0.1", 8989);
outputStream = socket.getOutputStream();
outputStream.write(info.getBytes());
outputStream.flush();
socket.shutdownOutput();
// 接受服务器返回的消息
InputStream inputStream = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(inputStream));
System.out.println("服务器返回消息说:"+br.readLine());
}catch (IOException e1) {
e1.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
}
}
}
@Test
public void testClientThread2(){
while(true){
InputStream is=null;
InputStreamReader isr=null;
BufferedReader br=null;
try {
is = System.in;
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String info=null;
while((info=br.readLine())!=null){//循环读取客户端的信息
System.out.println("当前输入的信息是:"+info);
ClientThread thread = new ClientThread(info);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void testServer(){
try{
ServerSocket server = new ServerSocket(8989);
Socket socket=null;
//记录客户端的数量
int count=0;
System.out.println("***服务器即将启动,等待客户端的连接***");
//循环监听等待客户端的连接
while(true){
//调用accept()方法开始监听,等待客户端的连接
socket=server.accept();
count++;//统计客户端的数量
System.out.println("建立了socket实例时间:"+new Date()+",当前客户端的数量:"+count+",当前的socket:"+socket.hashCode());
// InetAddress inetAddress = socket.getInetAddress();
// System.out.println("当前的IP:"+inetAddress.getHostAddress()+",当前的本地主机IP:"+inetAddress.getLocalHost()+",当前的socket 是"+socket.hashCode());
//获取远程请求地址和端口
InetAddress inetAddress = socket.getInetAddress();
int port = socket.getPort();
String hostAddress = inetAddress.getHostAddress();
String hostName = inetAddress.getHostName();
InetAddress localHost = inetAddress.getLocalHost();
System.out.println("远程主机 :"+inetAddress+",远程端口:"+port+",远程hostAddress:"+hostAddress+",远程hostName:"+hostName);
//获取发起的地址和端口
InetAddress localAddress = socket.getLocalAddress();
int localPort = socket.getLocalPort();
String hostAddress2 = localAddress.getHostAddress();
String hostName2 = localAddress.getHostName();
System.out.println("本地主机 :"+localAddress+",本地端口 :"+localPort+",本地hostAddress:"+hostAddress2+",本地hostName:"+hostName2);
//创建一个新的线程
ServerThread serverThread=new ServerThread(socket);
//启动线程
serverThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}