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,所以后期加上密码算法之后,聊天的用户体验就可能会受到网速(收发数据)、计算机硬件(加解密与验证的速度)的制约,但是我们的程序规模又不是特别大,效果上会影响的可能没有想象的那么大。