基于TCP的简单服务器
基于Tcp的简单服务器
- UDP协议无连接类似于发微信
- TCP协议有链接类似于打电话
- 所以基于TCP的服务器先要到内核中获取一个TCP连接,UDP不需要获取连接
- TCP的连接管理是由操作系统的内核来管理的,客户端和服务器建立连接的过程中,完全由内核来进行负责。负责程序的代码感知不到
- TCP的来连接管理需要先描述在组织
- 描述:通信的五元组
- 组织:使用一个阻塞队列来组织若干个连接对象
- 代码中调用这个accept方法就是从阻塞队列当中获取一个链接对象(在应用程序中的化身就是Socket对象)
- 后续数据读写都是根据这个clientSocket这个对象来进行展开的
- 如果都服务器启动之后,没有客户端建立连接,此时代码中调用accpt方法就会阻塞,阻塞到真的有客户端建立连接为止。
- 简单的TCP服务器
package com.zb.network.test;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;/*** @Description: 基于Tcp的简单服务器* @Author:啵啵啵啵啵啵唧~~~* @Date:2022/5/4*/
public class TcpEchoServer {/*** 1、初始化服务器* 2、进入主循环* 1.先去从内核当中获取到一个TCP连接* 2.处理这个TCP连接* a.读取请求并解析* b.根据请求计算响应* c.把响应写回给客户端*//*** 创建于给serverSocket对象*/private ServerSocket serverSocket = null;/*** 构造方法,初始化serverSocket对象** @param port* @throws IOException*/public TcpEchoServer(int port) throws IOException {//这个操作和UDP类似需要绑定端口号serverSocket = new ServerSocket(port);}/*** 启动服务器** @throws IOException*/public void start() throws IOException {System.out.println("服务器启动");while (true) {//1.先从内核当中获取一个TCP连接,当客户端没有连接过来的时候,accept就会陷入阻塞Socket clientSocket = serverSocket.accept();//2.处理这个链接processConnection(clientSocket);}}/*** 处理连接的方法* 一个连接中客户端和服务器之交互一次么?* 服务器的处理方式有两种* 1.一个连接中客户端和服务器只交互一次,交互完毕,就断开连接(短连接)* 2.一个连接中,客户端和服务器之间交互N次,直到满足一定的条件再断开连接(长连接)* 其中长连接的效率小队来说效率高一些** @param clientSocket*/private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d]客户端上线\n", clientSocket.getInetAddress().toString(),clientSocket.getPort());//通过clientSocket来和客户端交互,先做好准备工作,获取到clientSocket中的流对象try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))){//此处实现一个长连接的版本,一次处理的过程当中,需要处理多个请求和响应//当客户端断开连接的时候,服务器再去调用readLine或者write方法都会触发异常(IOException)while (true) {//1.读取请求并解析//此处暗含一个重要的信息,客户端发的数据必须是一个按行发送的数据(每条数据一行)String request = bufferedReader.readLine();//2.根据请求计算响应String response = process(request);//3.把响应写回到客户端(客户端按行来读)bufferedWriter.write(response + "\n");//手动刷新缓冲区bufferedWriter.flush();System.out.printf("[%s:%d] req: %s; resp: %s\n", clientSocket.getInetAddress().toString(),clientSocket.getPort(), request, response);}} catch (IOException e) {System.out.printf("[%s:%d]客户端下线\n", clientSocket.getInetAddress().toString(),clientSocket.getPort());}}/*** 根据请求计算响应** @param request* @return*/private String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(9090);server.start();}
}
- TCP客户端
package com.zb.network.test;import java.io.*;
import java.net.Socket;
import java.util.Scanner;/*** @Description:* @Author:啵啵啵啵啵啵唧~~~* @Date:2022/5/4*/
public class TcpEchoClient {//1.启动客户端(一定不要绑定端口号)和服务器建立连接//2.进入主循环// a.读取用户输入的内容// b.构造一个请求发送给服务器// c.读取服务器响应的数据// d.把响应数据显示到界面上private Socket socket = null;/*** 实例化socket* @param serverIp* @param serverPort* @throws IOException*/public TcpEchoClient(String serverIp, int serverPort) throws IOException {//此处实例化就是建立TCP连接(三次握手的过程)socket = new Socket(serverIp,serverPort);}public void start(){System.out.println("客户端启动");Scanner sc = new Scanner(System.in);try( //获取两个流对象BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {while (true){//读取用户输入的内容System.out.print("->");String request = sc.nextLine();if ("exit".equals(request)){break;}//2.客户端构造请求并发送.此处+\n为了和服务器中的readLine向对应bufferedWriter.write(request + "\n");//刷新缓存bufferedWriter.flush();//3.客户端读取响应数据。String response = bufferedReader.readLine();//4.把响应数据显示到界面上.System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);client.start();}}
注意
- UDP中必须用receive和send.传输数据的基本单位是DatagramPacket对象.[面向数据报]
- TCP中必须用read和write,传输数据的基本单位是字节.[面向字节流 ]
- 他们传输协议上的差异导致代码的差异
- Tcp要刷新缓冲区的作用
//--------------------服务器刷新缓冲区-----------------------//3.把响应写回到客户端(客户端按行来读)bufferedWriter.write(response + "\n");//手动刷新缓冲区bufferedWriter.flush(); //----------------------客户端刷新缓冲区----------------------//2.客户端构造请求并发送.此处+\n为了和服务器中的readLine向对应bufferedWriter.write(request + "\n");//刷新缓存bufferedWriter.flush();
解决Tcp连接只能有一个客户端连接服务器的问题
- 原因就是accept方法的调用,调用几个accept方法就处理几个连接,在代码中出现的问题就是由于为了要实现长连接,导致循环退不出去,导致accept方法无法正常调用,所以只能有一个客户端和服务器进行连接
- 解决方法就是使用多线程,用一个线程专门来调用accept方法从而实现并发操作,这样既可以实现长连接又可以正常调用accept方法,其实单线程的方式也可以解决,使用IO多路复用即可,而且十分高效,但是比较麻烦
- 这样就可以让多个客户端同时连接服务器
基于TCP的简单服务器相关推荐
- C++基于TCP/IP简单的客户端、服务器通信程序实例
本篇文章实现了一个基于TCP 的一个非常简单的客户/服务器通信程序实例.该程序中通讯协议使用的是面向连接的TCP协议SOCK_STREAM, 服务器的ip地址为本地地址即: 127.0.0.1,端口号 ...
- 基于 TCP Socket 的服务器与客户端的简单连接
简单的讲下流程: 1. 服务器会创建一个监听 socket, 用来监听客户端的连接请求,接着配置一下监听 socket 的 IP.port.protocol 2. 绑定配置好的信息 以及监听 sock ...
- Android 端的基于TCP的小型服务器_超级简单
服务端代码: HttpServer: package example.com.httpserver;import android.graphics.Bitmap; import android.gra ...
- 基于TCP实现简单网络计算器
这里我们需要简单实现网络版的计算器,我打算让它具有计算加法,减法,乘法,除法,还有取模 的功能. 例如(加法),我们需要实现一个服务器版的加法器,我们需要客户端把要计算的两个加数发过去,然后由服务端进 ...
- Java案例:基于TCP的简单聊天程序
文章目录 一.如何实现TCP通信 二.编写C/S架构聊天程序 (一)编写服务器端程序 - Server.java (二)编写客户端程序 - Client.java (三)测试服务器端与客户端能否通信 ...
- 江南大学C语言大作业,TCPIP大作业基于TCP的网络通信编程C语言版(江南大学).doc...
TCPIP大作业基于TCP的网络通信编程C语言版(江南大学).doc TCP/IP协议编程大作业 课题名称 基于TCP的网络通信 专 业 计算机科学与技术 班 级 计算机1206 学 号 103041 ...
- 网络编程——基于TCP协议的通讯录【课程设计】
网络编程--基于TCP协议的通讯录[课程设计] 本文目录 网络编程--基于TCP协议的通讯录[课程设计] 一.设计题目和要求 设计目标: 课程设计系统组成及模块功能: 二.设计内容 服务端 客户端 S ...
- 打印服务器协议,基于TCP/IP协议的嵌入式网络打印服务器设计
摘要: 随着电子技术和计算机网络技术的发展,嵌入式系统在家庭和工业的各个领域都得到了广泛的应用,各种信息家电,网络设备以及工业控制领域都出现了嵌入式系统的身影,其数量已经远远超过了各种通用计算机.但是 ...
- Linux系统下实现基于TCP/IP协议的简单Socket通信
Linux系统下实现基于TCP/IP协议的简单Socket通信 网络套接字Socket Socket概念 主机字节序和网络字节序 Sockaddr地址结构 Socket实现客户端.服务端通信 服务端程 ...
最新文章
- 冰刃——IceSword
- 使用阿里云的maven私服的setting.xml, 提高maven项目jar下载速度
- 使用sed,awk将love转换成LOVE,将CHINA转换成china
- C++ Primer 5th笔记(chap 14 重载运算和类型转换)输入和输出运算符
- extern使用说明
- 【华为云技术分享】GitHub联合开发
- html5学习笔记---05.JavaScript 中的面向对象,继承和封装
- mockit学习(一)
- 自定义日历控android,android 一个简单的自定义日历控件,让你掌控时间
- Flash CS4学习笔记1
- 项目采集自动刷新 php,PHP168 CMS自动采集-PHP168 CMS自动更新-齐博CMS站群管理系统...
- kafka错误代码解释
- Vue项目实战:订单列表页面实现
- DEVc++迷你世界0.10.0
- 浅聊一下Java中的char类型
- 小米9私密相册怎么找_小米手机私密相册怎么用?怎么打开查看?
- 耦合(六种)与 内聚(七种)—《软件工程与计算》笔记
- 远程桌面连接出现身份验证错误。要求的函数不受支持。这可能是由于CredSSP加密数据库修正。
- 23.Odoo产品分析 (三) – 人力资源板块(4) – 招聘流程(1)
- cct考试模拟试题c语言,计算机一级(CCT)考试模拟题