Java中的Socket编程:
Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一。如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的。本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序。
TCP和UDP通信
关于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文档
来源:https://www.cnblogs.com/snail-lb/p/5468054.html