Socket:套接字,用于java网络编程的接口和一种机制,用套接字中的相关函数来建立连接和完成通信,socket可以看成在两个程序进行通信连接中的一个端点。
将区分不同应用程勋进程的三个参数1.通信的目的地IP地址 2.使用的传输层协议 3.使用的端口号与一个socket绑定。
1.每一个socket用一个半相关描述:(协议,本地地址,本地端口)
2.“套接字”或者“插座”(socket)也是一种软件形式的抽象,用于表达两台机器之间一个连接的“终端”。针对一个特定的连接,每台机器上都有一个“套接字”,可以想象他们之间有一条虚拟的“线缆”。线缆的每一端都插入一个“套接字”或“插座”里。
3.套接字,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。
应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需通过同一个TCP协议端口传输数据。为了区别不同的应用程序和连接,许多计算机操作系统为应用程序与TCP/IP协议提供了称为套接字(Socket)的接口。
4.区分不同应用程序进程间的网络通信和连接,主要有三个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。Socket原意是“插座”。通过将这三个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
5.Socket可以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。
基于TCP的Scoket编程
利用TCP协议进行通信两个应用程序,有主从之分,一个称为Server,另一个称为Client。
交互过程
1.服务器程序创建一个ServerSocket,然后调用accept方法等待客户机来连接。
2.客户端程序创建一个Socket并请求与服务器简历连接。
3.刚才建立了连接的两个Socket在一个单独的线程上对话。
4.服务器开始等待新的连接。
1 public class Server { 2 private static ServerSocket serverSocket; 3 4 //自己请求本机访问一次。 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 try { 8 serverSocket = new ServerSocket(8888); 9 Socket socket = null; 10 int count = 0; 11 // 2.调用accep()方法开始监听,等待客户端请求。 12 System.out.println("**服务器已经启动,等待请求**"); 13 while (true) { 14 socket = serverSocket.accept(); 15 ServerThread serverThread = new ServerThread(socket); 16 serverThread.start(); 17 count++; 18 System.out.println("当前客户端的数量是:"+count); 19 } 20 } catch (IOException e) { 21 // TODO Auto-generated catch block 22 e.printStackTrace(); 23 } 24 25 } 26 27 }
1 public class Client { 2 3 public static void main(String[] args) { 4 try { 5 // 创建客户端socket,指定服务器的地址和端口 6 Socket socket = new Socket("192.168.74.2", 8888); 7 // 获取输出流,字节流。 8 OutputStream outputStream = socket.getOutputStream(); 9 PrintWriter out = new PrintWriter(outputStream); 10 out.write("用户名:admin;密码:135"); 11 out.flush(); 12 socket.shutdownOutput(); 13 // 客户端接收服务器端响应 14 InputStream is = socket.getInputStream(); 15 BufferedReader br = new BufferedReader(new InputStreamReader(is)); 16 String data = null; 17 while ((data = br.readLine()) != null) { 18 System.out.println("我是客户端,服务器端说:" + data); 19 } 20 br.close(); 21 is.close(); 22 out.close(); 23 outputStream.close(); 24 socket.close(); 25 } catch (UnknownHostException e) { 26 e.printStackTrace(); 27 } catch (IOException e) { 28 e.printStackTrace(); 29 } 30 31 } 32 33 }
public class ServerThread extends Thread { Socket socket = null; public ServerThread(Socket socket) { this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub // 3.获取输入的字节流 InputStream in = null; // 将字节流装换为字符流 InputStreamReader isr = null; // 为字符流设置缓冲区 BufferedReader br = null; // 服务器端响应 OutputStream os = null; PrintWriter out = null; try { in = socket.getInputStream(); isr = new InputStreamReader(in); br = new BufferedReader(isr); String data = null; while ((data = br.readLine()) != null) { System.out.println("我是服务器,客户端说:" + data); } socket.shutdownInput(); os = socket.getOutputStream(); out = new PrintWriter(os); out.write("客户端,你好!"); out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 关闭socket输入流 try { out.close(); os.close(); br.close(); isr.close(); in.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
基于UDP的网络传输
public class UDPServer { private static DatagramSocket datagramSocket; public static void main(String[] args) throws IOException { /** * 服务器端接收客户端的信息 */ datagramSocket = new DatagramSocket(8800); // 2.指定字节数组用来接收数据 byte[] bytes = new byte[1024]; DatagramPacket packet = new DatagramPacket(bytes, bytes.length); System.out.println("**服务器端已经启动**"); // 3.接收客户端发送的数据 datagramSocket.receive(packet); String data = null; data = new String(bytes, 0, packet.getLength()); System.out.println("我是服务端,客户端的数据是:" + data); /** * 服务器端响应客户端 */ InetAddress address = packet.getAddress(); int port = packet.getPort(); byte[] bytes2 = "客户端你好!".getBytes(); DatagramPacket packet2 = new DatagramPacket(bytes2, bytes2.length, address, port); DatagramSocket socket = new DatagramSocket(); socket.send(packet2); socket.close(); } }
public class UDPClient { private static DatagramSocket socket; public static void main(String[] args) throws IOException { /** * 客户端想服务器端发送数据 */ InetAddress address = InetAddress.getByName("192.168.74.2"); int port = 8800; byte[] bytes = "用户名:admin,密码:123".getBytes(); DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port); socket = new DatagramSocket(); socket.send(packet); /** * 客户端接收阢器端的数据 */ // datagramSocket = new DatagramSocket(8800); // 2.指定字节数组用来接收数据 byte[] bytes2 = new byte[1024]; DatagramPacket packet2 = new DatagramPacket(bytes2, bytes2.length); // 3.接收服务器端发送的数据 socket.receive(packet2); String data = null; data = new String(bytes2, 0, packet2.getLength()); System.out.println("我是客户端,服务器端说:" + data); } }
TCP是较可靠的双向流协议,可以发送任意数量的数据,提供消息确认、错误监测和错误恢复等服务。
UDP不可靠。