socket网络编程
一、socket
Java的网络编程主要涉及到的内容是Socket编程。Socket,套接字,就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。
应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
Socket,实际上是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。实际上,Socket跟TCP/IP协议没有必然的关系,Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket的出现,只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口,比如create、listen、accept、send、read和write等等。网络有一段关于socket和TCP/IP协议关系的说法比较容易理解:
“TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。这个就像操作系统会提供标准的编程接口,比如win32编程接口一样,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。”
二、流程
Socket编程主要涉及到客户端和服务端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。
客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。

三、实例
1.server
public class SocketServerM { public static void main(String[] args) throws IOException { int port=7000; int clientNo=1; ServerSocket serverSocket=new ServerSocket(port); //创建线程池 ExecutorService exec= Executors.newCachedThreadPool(); try { while (true) { Socket socket = serverSocket.accept(); System.out.println("客户端"+clientNo+"已连接"); exec.execute(new SingleServer(socket, clientNo)); clientNo++; } }finally { serverSocket.close(); } } } class SingleServer implements Runnable{ private Socket socket; private int clientNo; public SingleServer(Socket socket,int clientNo){ this.socket=socket; this.clientNo=clientNo; } @Override public void run(){ try { DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); do { double length = dis.readDouble(); System.out.println("从客户端" + clientNo + "接收到的边长数据为:" + length); double result = length * length; dos.writeDouble(result); System.out.println("返回客户端"+clientNo+"结果:"+result); dos.flush(); } while (dis.readInt() != 0); } catch (IOException e) { e.printStackTrace(); } finally { System.out.println("与客户端" + clientNo + "通信结束"); try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
2.client
public class SocketClient1 { public static void main(String[] args) { SocketClient1 sc=new SocketClient1(); System.out.println("connecting..."); try { sc.area(); } catch (ConnectException|InterruptedException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e){ e.printStackTrace(); } finally { System.out.print("---END---"); } } public void area()throws ConnectException,InterruptedException, IOException { int port = 7000; String host="localhost"; //创建一个套接字并将其连接到指定端口号 Socket socket=new Socket(host,port); Thread.sleep(1000); DataInputStream dis=new DataInputStream(new BufferedInputStream(socket.getInputStream())); DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); Scanner sc=new Scanner(System.in); boolean flag=true; while(flag){ System.out.print("正方形边长:"); double length=sc.nextDouble(); dos.writeDouble(length); dos.flush(); double area=dis.readDouble(); System.out.println("socket server返回的计算面积为:"+area); while(true){ System.out.print("继续计算(Y/N):"); String str=sc.next(); if(str.equalsIgnoreCase("N")){ dos.writeInt(0); dos.flush(); flag=false; break; }else if(str.equalsIgnoreCase("Y")){ dos.writeInt(1); dos.flush(); break; } } } socket.close(); } }
参考:
https://www.cnblogs.com/swordfall/p/10781281.html#auto_id_18

浙公网安备 33010602011771号