基于Socket的TCP编程

Java语言的基于套接字编程分为服务端编程和客户端编程,其通信模 型如图所示:

image-20201031170502815

客户端Socket的工作过程包含以下四个基本的步骤:

  • 创建Socket:根据指定服务端的 IP 地址或端口号构造 方法Socket()构造 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
  • 打开连接到 Socket 的输入/出流: 使用getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输.
  • 按照一定的协议对Socket 进行读/写操作:通过输入流读取服务器放入线路的信息 (但不能读取自己放入线路的信息),通过输出流将信息写入线程。
  • 关闭 Socket:断开客户端到服务器的连接,释放线路

服务器程序的工作过程包含以下四个基本的步骤:

  • 调用ServerSocket(int port):创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
  • 调用accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信 套接字对象。
  • 调用 该Socket类对象的 getOutputStream()getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
  • 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

image-20201031202038814

客户端发送信息给服务端,服务端将数据显示在控制台上

image-20201031193154841

先启动客户端报错。TCP需要建立连接。所以要先启动服务端在启动客户端。

image-20201031201448787

2020-10-31 19.33.27

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

public class TCPTest1 {

//客服端
@Test
public void client() throws IOException {
//1.创建Socket对象,指明服务器的ip和端口号 本机ip
InetAddress localHost = InetAddress.getLocalHost();//获取本机ip InetAddress对象
InetAddress inet = InetAddress.getByName("192.168.1.1");//通过本机ip 获取InetAddress对象
Socket socket = new Socket(localHost, 8899);
//2.获取输出流,用于输出数据
OutputStream os = socket.getOutputStream();
//3.写出数据
os.write("你好我是客户端".getBytes());

//4.关闭资源
os.close();
socket.close();
}

//服务端
@Test
public void server() throws IOException {
//1.创键SocketServer对象
ServerSocket serverSocket = new ServerSocket(8899);
//2.调用accept()表示接受客户端的socket
Socket socket = serverSocket.accept();
//3.获取输入流
InputStream is = socket.getInputStream();
//4.读取输入流中的数据
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
String str = new String(buffer, 0, len);
System.out.print(str);
}
//5.关闭资源
is.close();
socket.close();
serverSocket.close();
}
}

客户端发送文件给服务端,服务端将文件保存在本地。

image-20201031195408714

socket.shutdownOutput();

image-20201031195506716

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class TCPTest2 {
//这里涉及到的异常,应该使用try-catch-finally处理
@Test
public void client() throws IOException {
//1.创建Socket对象,指明服务器的ip和端口号 本机ip
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
//2.获取输出流,用于输出数据
OutputStream os = socket.getOutputStream();
//3.创建文件输入流
FileInputStream fis = new FileInputStream(new File("wallhaven-39dxld.jpg"));
//4.读写文件
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//5.资源关闭
fis.close();
os.close();
socket.close();
}
@Test
public void server() throws IOException {
//1.创键SocketServer对象
ServerSocket ss = new ServerSocket(9090);
//2.调用accept()表示接受客户端的socket
Socket socket = ss.accept();
//3.获取输入流
InputStream is = socket.getInputStream();
//4.创建文件输出流
FileOutputStream fos = new FileOutputStream(new File("copy.jpg"));
//5.读写文件
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
//6.关闭资源
fos.close();
is.close();
socket.close();
ss.close();
}
}

从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。

image-20201031201213160

image-20201031201308671

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* 实现TCP的网络编程
* 例题3:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。
* 并关闭相应的连接。
*/
public class TCPTest3 {
// 这里涉及到的异常,应该使用try-catch-finally处理
@Test
public void client() throws IOException {
//1.
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
//2.
OutputStream os = socket.getOutputStream();
//3.
FileInputStream fis = new FileInputStream(new File("copy.jpg"));
//4.
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//关闭数据的输出
socket.shutdownOutput();
//5.接收来自于服务器端的数据,并显示到控制台上
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bufferr = new byte[20];
int len1;
while ((len1 = is.read(buffer)) != -1) {
baos.write(buffer, 0, len1);
}
System.out.println(baos.toString());
//6.
fis.close();
os.close();
socket.close();
baos.close();
}

@Test
public void server() throws IOException {
//1.
ServerSocket ss = new ServerSocket(9090);
//2.
Socket socket = ss.accept();
//3.
InputStream is = socket.getInputStream();
//4.
FileOutputStream fos = new FileOutputStream(new File("copy2.jpg"));
//5.
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("图片传输完成");
//6.服务器端给予客户端反馈
OutputStream os = socket.getOutputStream();
os.write("发送成功!!".getBytes());

//7.关闭资源
fos.close();
is.close();
socket.close();
ss.close();
os.close();
}
}