20175323 团队项目 服务器端函数功能与业务逻辑详解

20175323 团队项目服务器端函数功能与业务逻辑详解

本博客对于团队项目的服务器端程序的函数功能做出了解释,并对于整个应用系统的服务器端的业务逻辑做出了解释


Socket在服务器和客户端之间建立连接并进行数据交互的过程

流程图(时序图)


预想的每一步的操作过程都已经体现在流程图中了

UML类图

所以总计需要四个类:客户端、服务器、发送、接收,客户端和服务器分别对发送和接收都有依赖关系
UML类图如下

编写代码实现socket收发消息的功能

客户端程序

package com.wenqier.client;

import java.net.*;
import java.io.*;

//聊天过程用于发送信息的线程
class Send extends Thread {
	Socket socket;

	public Send(Socket sock) {
		this.socket = sock;
	}
	// 专门用于发送信息
	public void run() {
		DataOutputStream out;
		while (true) {
			BufferedReader input = new BufferedReader(new InputStreamReader(
					System.in));
			try {
				String str;
				str = input.readLine();
				out = new DataOutputStream(socket.getOutputStream());
				out.writeUTF(str);
			} catch (Exception e) {
			}
		}

	}
}

// 创建一个专门用于接收消息的线程
class Receive extends Thread {
	Socket socket;

	public Receive(Socket sock) {
		this.socket = sock;
	}

	public void run() {
		// 专门用于接收消息
		DataInputStream in;
		while (true) {
			try {
				in = new DataInputStream(socket.getInputStream());
				String str = in.readUTF();
				System.out.println(str);
			} catch (Exception e) {
			}
		}
	}
}

public class Client {

	static Socket socket;

	public static void main(String[] args) throws Exception {

		socket = new Socket("127.0.0.1", 5678);

		System.out.println("客户端.....");
		try {
			Send send = new Send(socket);
			Receive receive = new Receive(socket);
			// 打开线程
			send.start();
			receive.start();
		} catch (Exception e) {
		}
	}
}

服务器端程序

package com.wenqier.service;

import java.net.*;
import java.io.*;

//聊天过程中新建一个专门用于发送信息的线程
class Send extends Thread {
	Socket socket;

	public Send(Socket sock) {
		this.socket = sock;
	}
	// 专门用于发送信息
	public void run() {
		DataOutputStream out;
		while (true) {
			BufferedReader input = new BufferedReader(new InputStreamReader(
					System.in));
			try {
				String str;
				str = input.readLine();
				out = new DataOutputStream(socket.getOutputStream());
				out.writeUTF(str);
			} catch (Exception e) {
			}
		}

	}
}

// 创建一个专门用于接收消息的线程
class Receive extends Thread {
	Socket socket;

	public Receive(Socket sock) {
		this.socket = sock;
	}

	public void run() {
		// 专门用于接收消息
		DataInputStream in;
		while (true) {
			try {
				in = new DataInputStream(socket.getInputStream());
				String str = in.readUTF();
				System.out.println(str);
			} catch (Exception e) {
			}
		}
	}
}

public class Service {
	// 声明ServerSocket类对象
	static ServerSocket service;

	public static void main(String[] args) {
		try {
			service = new ServerSocket(5678);

			System.out.println("服务器端.....");
			Socket client = null;

			client = service.accept();

			Send send = new Send(client);
			Receive receive = new Receive(client);
			// 打开线程
			send.start();
			receive.start();
		} catch (Exception e) {
		}
	}
}

程序运行结果

运行程序在命令行里输出这个是客户端

客户端发送消息hello!

服务器端正常接收到了消息hello!,发回一个你好!

客户端正常接收到了发来的你好

实践收获

除了Java 的socket编程和多线程编程之外,通过查找资料我还有如下的收获

JAVA Socket和C Socket的比较

通过之前教材和本次实践学习的JAVA Socket与学长用例子给我讲socket的时候用的他编的C socket程序,我理解的两种socket的最主要不同有两个,就是面向对象与面向过程的不同和函数的封装的完备程度的不同。
我理解的面向对象与面向过程的不同最明显的就是C语言的socket程序,一般需要声明两个或者更多socket。这些套接字里必须要有一个socket调用accept方法监听客户端的连接请求,而accept方法返回的套接字描述符传给一个新的socket用来做数据交互,之前的socket继续监听。这样的机制能够保证服务器端一直有一个socket是监听状态。

而Java socket只要一个套接字就可以同时进行监听与数据传输,因为它可以调用Serversocket对象的获取输入以及输出流的成员函数来创建线程,用创建的线程实现数据交互,而这个主函数本身还可以继续监听客户端的请求。
另外一方面就是函数的封装,Java socket的库函数(确切的说是包)封装的非常完备,实现双方的数据交互全部的步骤也不到两三步。而C语言写socket就比这个要繁琐
C语言写socket要这样,地址和端口的绑定和监听都要自己写,而且函数参数貌似比Java复杂

用Java写tcp socket更加容易,目前更有助于我们理解计网学的tcp协议

客户端与服务器socket的比较

这个程序使用的是面向连接的socket,因此客户端和服务器都是socket但是有一些不同存在,就是服务器端要用accept方法接收客户端的连接请求

实际生活中socket的使用与一部分思考

实际生活中的应用系统,用的大多是面向无连接的socket,即使用的是udp协议的socket。比如说我们用的微信和QQ。因为,udp虽然无连接、不可靠、尽最大努力交付,但是和tcp相比它的速度非常优秀,可以满足聊天的实时性的需求,而且微信发语音要的也是个速度。
但是我们为了准确而且安全,使用了tcp协议的面向连接的socket,所以后期加上密码算法之后,聊天的用户体验就可能会受到网速(收发数据)、计算机硬件(加解密与验证的速度)的制约,但是我们的程序规模又不是特别大,效果上会影响的可能没有想象的那么大。

posted @ 2019-06-02 22:32  20175323鞠欣余  阅读(331)  评论(0编辑  收藏  举报