Socket中文译作“套接字”,也称为伯克利套接字和BSD套接字(Berkeley Software Distribution,伯克利软件套件),BSD是伯克利大学基于早期UNIX系统的衍生系统。伯克利套接字
的应用编程接口(API)是使用C语言的进程间通信的库,经常用于计算机网络间通信。BSD Socket的应用编程接口已经是网络套接字的事实上的抽象标准。
BSD Socket作为一种API,允许不同主机或者同一个计算机上的不同进程之间的通信。它支持多种I/O设备和驱动,但是具体的实现是依赖操作系统的。这种接口对于TCP/IP是必不可少的,所以是互联网的基础技术之一。它最初是由加州伯克利大学为Unix系统开发出来的。所有现代的操作系统都都实现了伯克利套接字接口,因为它已经是连接互联网的标准接口了。
Socket连接过程分为三步:服务器监听,客户端请求,连接确认。以JAVA为例,Socket和ServerSocket类位于java.net包中,ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
JAVA中使用实例
服务端(Server)
import java.net.*; import java.io.*; import java.util.*; public class Server { boolean isstart = false;//用来判断 服务端是否已经起来了 //public DataInputStream dis = null; //public String str = null; public ServerSocket ss = null; //public Socket s = null; List<Client> clients = new ArrayList<>(); //DataOutputStream dos = null; public static void main(String[] args) //要多次调用readUTF()方法 Client端 发送多少次给服务端 服务端就要接受多少次 用到死循环 { new Server().start(); } public void start() { try { ss = new ServerSocket(8888);//服务端起来了 isstart = true;//服务端起来后 将其设置为 true } catch(BindException e)//这个异常一定要 先比 IOException 先 捕获 不然 如果先捕获 IOException 这个 异常就捕获不了了 然后就会报错 提示要先捕获 这个异常 { System.out.println("端口使用中……"); System.out.println("请关掉服务端 ,然后重新启动服务端。"); System.exit(0); } catch(IOException e) { e.printStackTrace(); } try { while(isstart)//服务端起来后就一直 循环 检测是否有客户端连接 { Socket s = ss.accept();//客户端连接到服务端后 设置其为true System.out.println("a client connect"); Client c = new Client(s); clients.add(c); new Thread(c).start(); } } catch(IOException e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } class Client implements Runnable { private Socket s = null; private DataInputStream dis = null; DataOutputStream dos = null; private boolean isconnect = false; Client(Socket s) { this.s = s; try { dis = new DataInputStream(s.getInputStream());//客户端连接到服务端后 设置isconnect = true dos = new DataOutputStream(s.getOutputStream()); isconnect = true; } catch (IOException e) { e.printStackTrace(); } } public void send(String str) { try { dos.writeUTF(str); dos.flush(); } catch (IOException e) { clients.remove(this); System.out.println("a client quit"); } } @Override public void run() { try { while(isconnect)//客户端连接服务端后 循环 以便 接受 客户端 每一次发送的消息 { //dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); System.out.println(str); for(int i=0;i<clients.size();i++) { Client c = clients.get(i); c.send(str); } //dis.close(); //ss.close(); } //dis.close();//当服务端没有起来 或者 客户端没有连接 到服务端 就将管道关闭*/ } catch(EOFException e) { System.out.println("Client disconnect!"); } catch (IOException e) { e.printStackTrace(); } finally { try { if(dis!=null) dis.close(); if(s!=null) s.close(); } catch(IOException e) { e.printStackTrace(); } System.out.println("Client disconnect!"); } } } }
客户端(Client)
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Client extends Frame { TextField txf = new TextField(); //TextField txf = null; //应该先要进行初始化 不然 txa.setText(txa.getText()+str+" ");用于记录聊天记录的语句就会 每次都为null 记录保存不了 TextArea txa = new TextArea(); DataOutputStream dos = null; DataInputStream dis = null; Socket s = null; boolean isconnect = false; Thread receive = new Thread(new Receive());//new Receive()别忘了!! public static void main(String[] args) { new Client().lanuch(); } public void lanuch() { Frame frame = new Frame("Chat!"); frame.setLayout(new BorderLayout()); frame.setLocation(200,300); frame.setSize(200, 150); //txf = new TextField(); //txa = new TextArea(); frame.add(txf, BorderLayout.SOUTH);//增加两个框架的顺序也是有先后的 frame.add(txa, BorderLayout.CENTER);// txf.addActionListener(new TxfListener()); //txa.setEditable(false); frame.pack(); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { disconnect(); System.exit(0); } }); connected(); } public void disconnect() { try { dos.close(); s.close(); } catch(IOException e) { e.printStackTrace(); } } public void connected() { try { s = new Socket("127.0.0.1",8888); dos = new DataOutputStream(s.getOutputStream()); dis = new DataInputStream(s.getInputStream()); isconnect = true; receive.start(); } catch(IOException e) { e.printStackTrace(); } System.out.println("connect"); } class Receive implements Runnable { public void run() { try { while(isconnect) { String str = dis.readUTF(); txa.setText(txa.getText()+str+" "); } } catch(SocketException e) { System.out.println("系统退出……"); } catch(IOException e) { e.printStackTrace(); } } } private class TxfListener implements ActionListener { public void actionPerformed(ActionEvent e) { String str = txf.getText(); //txa.setText(str); txf.setText(""); try { dos.writeUTF(str); dos.flush(); //dos.close(); //s.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
参考文章:https://blog.csdn.net/wang_hua_yi/article/details/17382015