标签:
Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一。如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的。本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序。
关于socket编程我们有两种通信协议可以进行选择。一种是数据报通信,另一种就是流通信。
数据报通信协议,就是我们常说的UDP(User Data Protocol 用户数据报协议)。UDP是一种无连接的协议,这就意味着我们每次发送数据报时,需要同时发送本机的socket描述符和接收端的socket描述符。因 此,我们在每次通信时都需要发送额外的数据。
流通信协议,也叫做TCP(Transfer Control Protocol,传输控制协议)。和UDP不同,TCP是一种基于连接的协议。在使用流通信之前,我们必须在通信的一对儿socket之间建立连接。其中一个socket作为服务器进行监听连接请求。另一个则作为客户端进行连接请求。一旦两个socket建立好了连接,他们可以单向或双向进行数据传输。
读到这里,我们多少有这样的疑问,我们进行socket编程使用UDP还是TCP呢。选择基于何种协议的socket编程取决于你的具体的客户端-服务器端程序的应用场景。下面我们简单分析一下TCP和UDP协议的区别,或许可以帮助你更好地选择使用哪种。
在UDP中,每次发送数据报时,需要附带上本机的socket描述符和接收端的socket描述符。而由于TCP是基于连接的协议,在通信的socket对之间需要在通信之前建立连接,因此会有建立连接这一耗时存在于TCP协议的socket编程。
在UDP中,数据报数据在大小上有64KB的限制。而TCP中也不存在这样的限制。一旦TCP通信的socket对建立了连接,他们之间的通信就类似IO流,所有的数据会按照接受时的顺序读取。
UDP是一种不可靠的协议,发送的数据报不一定会按照其发送顺序被接收端的socket接受。然后TCP是一种可靠的协议。接收端收到的包的顺序和包在发送端的顺序是一致的。
简而言之,TCP适合于诸如远程登录(rlogin,telnet)和文件传输(FTP)这类的网络服务。因为这些需要传输的数据的大小不确定。而 UDP相比TCP更加简单轻量一些。UDP用来实现实时性较高或者丢包不重要的一些服务。在局域网中UDP的丢包率都相对比较低。
客户端编写:
首先要新建一个socket:其中127.0.0.1是你要连接的机器,4000是机器进行通信的端口好
1 Socket socket = new Socket("127.0.0.1", 4000);
然后需要从终端中不停的监听读取数据,然后再写出来,客户端完整程序:
1 package org.net; 2 3 import java.net.*; 4 import java.io.*; 5 public class MainClient 6 { 7 public static void main(String[] args) throws Exception 8 { 9 Socket socket = new Socket("127.0.0.1", 4000); 10 new ClientInputThread(socket).start(); 11 new ClientOutputThread(socket).start(); 12 } 13 } 14 15 class ClientOutputThread extends Thread 16 { 17 private Socket socket; 18 public ClientOutputThread(Socket socket) 19 { 20 super(); 21 this.socket = socket; 22 } 23 24 public void run() 25 { 26 try 27 { 28 OutputStream os = socket.getOutputStream(); 29 while (true) 30 { 31 BufferedReader reader = new BufferedReader( 32 new InputStreamReader(System.in)); 33 String line = reader.readLine(); 34 os.write(line.getBytes()); 35 } 36 } 37 catch (IOException e) 38 { 39 e.printStackTrace(); 40 } 41 } 42 } 43 44 class ClientInputThread extends Thread 45 { 46 private Socket socket; 47 public ClientInputThread(Socket socket) 48 { 49 super(); 50 this.socket = socket; 51 } 52 53 public void run() 54 { 55 try 56 { 57 InputStream is = socket.getInputStream(); 58 while (true) 59 { 60 byte[] buffer = new byte[1024]; 61 int length = is.read(buffer); 62 String str = new String(buffer, 0, length); 63 System.out.println(str); 64 } 65 } 66 catch (IOException e) 67 { 68 e.printStackTrace(); 69 } 70 } 71 72 }
服务器编写:
首先也要先建立一个服务端的ServerSocket,并指定和客户端一样的端口号,然后让服务器一直处于监听状态,等待连接
1 ServerSocket serverSocket = new ServerSocket(4000); 2 while (true) 3 { 4 // 一直处于监听状态,这样可以处理多个用户 5 Socket socket = serverSocket.accept(); 6 }
然后服务器端也要等待输入输出流,服务器端完整代码:
1 package org.net; 2 3 import java.io.*; 4 import java.net.*; 5 public class MainServer 6 { 7 public static void main(String[] args) throws Exception 8 { 9 ServerSocket serverSocket = new ServerSocket(4000); 10 while (true) 11 { 12 // 一直处于监听状态,这样可以处理多个用户 13 Socket socket = serverSocket.accept(); 14 15 // 启动读写线程 16 new ServerInputThread(socket).start(); 17 new ServerOutputThread(socket).start(); 18 } 19 } 20 } 21 22 23 class ServerInputThread extends Thread 24 { 25 private Socket socket; 26 27 public ServerInputThread(Socket socket) 28 { 29 super(); 30 this.socket = socket; 31 } 32 33 public void run() 34 { 35 try 36 { 37 // 获得输入流 38 InputStream is = socket.getInputStream(); 39 while (true) 40 { 41 byte[] buffer = new byte[1024]; 42 int length = is.read(buffer); 43 String str = new String(buffer, 0, length); 44 System.out.println(str); 45 } 46 } 47 catch (IOException e) 48 { 49 e.printStackTrace(); 50 } 51 } 52 } 53 54 class ServerOutputThread extends Thread 55 { 56 private Socket socket; 57 public ServerOutputThread(Socket socket) 58 { 59 super(); 60 this.socket = socket; 61 } 62 public void run() 63 { 64 try 65 { 66 OutputStream os = socket.getOutputStream(); 67 while (true) 68 { 69 BufferedReader reader = new BufferedReader( 70 new InputStreamReader(System.in)); 71 String line = reader.readLine(); 72 os.write(line.getBytes()); 73 } 74 } 75 catch (IOException e) 76 { 77 e.printStackTrace(); 78 } 79 } 80 }
java下面进行socket编程要比其他语言(比如c)要简单,java.net包下面有很多的类可以供我们进行调用,注意平时多查API文档
标签:
原文地址:http://www.cnblogs.com/snail-lb/p/5468054.html