socket定义
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
Socket的英文原义是"孔"或"插座"。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。
简单来说,我们网络上的那些数据可以看成自来水管里的那些水,那现在服务器就是 自来水厂 而客户端就是你自己的家,那架设在外面的那些水管就是光纤,电话线等等传播网络信号的介质,现在可以直接用个破水管捅到自来水厂,然后另一端再直接捅进你家吗??这肯定不行,不然我不想要水的时候,水厂还在往死里灌,家里不就水漫金山了,所以这个时候水厂想把水给你送过去就需要做个阀门然后通过这个阀门控制水的流量啊等等,你自己家也同样装一个阀门来控制,不然水费咋算啊,哈哈哈
编码实现
客户端代码
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Socket socket = null;//与服务器链接的套接字
Scanner fromKey = null;//键盘输入流
Scanner fromServer = null;//获取服务器发送的字节流
PrintWriter toServer = null;//向服务器发送的字节流
try {
//链接服务器的套接字
socket = new Socket("localhost",8866);
/*
* 注意:服务器端与客户端不能都先获取输入流,这样会导致socket阻塞
* */
//实例化从服务器读的字节流
fromServer = new Scanner(socket.getInputStream());
//实例化向服务器写的字节流
toServer = new PrintWriter(socket.getOutputStream());
//实例化键盘输入流
fromKey = new Scanner(System.in);
while(fromServer.hasNextLine()){
//阻塞等待服务器发送消息
String fromServerData = fromServer.nextLine();
System.out.println("服务器 :" + fromServerData);
System.out.print("我(客户端) :");
//获取输入的数据
String toServerData = fromKey.nextLine();
//发送给服务器
toServer.println(toServerData);
toServer.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
fromServer.close();
toServer.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
服务器代码
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) {
ServerSocket ServerSocket = null;//开放的套接字
Socket socket = null;//链接客户端的套接字
Scanner fromKey = null;//键盘输入流
Scanner fromClient = null;//获取从客户端读的字节流
PrintWriter toClient = null;//获取向客户端写的字节流
try {
ServerSocket = new ServerSocket(8866);
System.out.println("服务器已启动,等待客户端链接");
//链接客户端的套接字
socket = ServerSocket.accept();
//实例化向客户端写的字节流
toClient = new PrintWriter(socket.getOutputStream());
toClient.println("你好啊客户端!!!");
toClient.flush();
System.out.println("我(服务器端) : 你好啊客户端!!!");
/*
* 注意:服务器端与客户端不能都先获取输入流,这样会导致socket阻塞
* */
//实例化从服务器读的字节流
fromClient = new Scanner(socket.getInputStream());
//实例化键盘输入流
fromKey = new Scanner(System.in);
//阻塞等待客户端发送消息
while(fromClient.hasNextLine()){
String fromClientData = fromClient.nextLine();
System.out.println("客户端 :" + fromClientData);
System.out.print("我(服务器端) :");
//获取输入的数据
String toClientData = fromKey.nextLine();
//发送给客户端
toClient.println(toClientData);
toClient.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
fromClient.close();
toClient.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
实现效果
客户端
服务器端