首页 > 编程语言 >基于Socket编程,模拟TCP部分协议字段编程

基于Socket编程,模拟TCP部分协议字段编程

时间:2022-12-21 11:09:26浏览次数:45  
标签:Socket 编程 TCP client println new public out


注意:先启动服务端,再运行客户端
Client.java 客户端

package sdut.ligong.demo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.SocketTimeoutException;

/**
* 1001 建立连接请求
*
* 1002 确认请求 1003 开始发送信息
*
* 1004 断开连接请求
*
* @author Lenovo
*
*/
public class Client1 {

/**
* 参考TCP报文首部格式
*
* 1.源端口和目的端口 各 占2个字节 2序号 占 4 字节 3确认号 占4字节 4数据偏移 占4位 5保留 占6位 6紧急 URG
* 为1表示紧急指针字段有效 7确认 ACK 为1表示有效 8推送 PSH 9复位RST 10同步SYN 11终止FIN 12窗口 13检验和
* 14紧急指针 15选项
*/

// 自定义报文首部格式为 确认号+报文长度+尾部(占一个字节,用于标注存储报文长度的位数)

public static int ESTABLISH_CONNECTION = 1001; // 建立连接

public static int CONFIRM_CONNECTION = 1002; // 确认连接

public static int SEND_INFORMATION = 1003; // 发送报文

public static int TERMINATE_CONNECTION = 1004; // 关闭连接

public static int MESSAGE_LENGTH = 0; // 发送信息的长度

public static int LengthBit = 0;//长度位数

private static String content = null;

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

// 客户端请求与本机在20006端口建立TCP连接
Socket client = new Socket("127.0.0.1", 20006);

client.setSoTimeout(10000);

// 获取键盘输入
BufferedReader input = new BufferedReader(new InputStreamReader(
System.in));

// 获取Socket的输出流,用来发送数据到服务端
PrintStream out = new PrintStream(client.getOutputStream());

// 获取Socket的输入流,用来接收从服务端发送过来的数据
BufferedReader buf = new BufferedReader(new InputStreamReader(
client.getInputStream()));

boolean flag = true;

while (flag) {

System.out.print("请输入信息:");

content = input.readLine();

System.out.println("content is the "+content);

System.out.println("开始发送连接请求");


MESSAGE_LENGTH = 6;

// 发送1001 请求连接
out.println(ESTABLISH_CONNECTION + "" + MESSAGE_LENGTH+""+1);

// 发送数据到服务端

if ("bye".equals(content)) {
flag = false;
} else {
try {
// 从服务器端接收数据有个时间限制(系统自设,也可以自己设置),超过了这个时间,便会抛出该异常
String echo = buf.readLine();

if (echo.contains("1002")) {

System.out.println("请求被确认");

System.out.println("准备发送信息!");

MESSAGE_LENGTH = 4 + content.length() + 1;

int m = MESSAGE_LENGTH;
if(m+1==10){ //如果输入内容长度为4加上固定长度5,加上长度空间占位1,则报文总长度为10,长度空间需要再增一位
m=10;
}

boolean t = true;
LengthBit = 0;
while(t){
if(m==0){
t = false;
}else {
m=m/10;
LengthBit++;
}
}

MESSAGE_LENGTH+=LengthBit;//加上报文长度占的内存空间

//发送报文
out.println(SEND_INFORMATION +""+MESSAGE_LENGTH +""+content+""+LengthBit);


String echo2 = buf.readLine();
//解析报文
int num = Integer.parseInt(echo2.substring(echo2.length()-1));

System.out.println(echo2.substring(4+num, echo2.length()-1));
System.out.println(echo2);

} else {

System.out.println("请求连接被拒绝");

}

} catch (SocketTimeoutException e) {
System.out.println("超时,无响应");
}
}
}
input.close();
if (client != null) {
// 如果构造函数建立起了连接,则关闭套接字,如果没有建立起连接,自然不用关闭
client.close(); // 只关闭socket,其关联的输入输出流也会被关闭
}
}
}

Server1.java

package sdut.ligong.demo;

import java.net.ServerSocket;
import java.net.Socket;

public class Server1 {
public static void main(String[] args) throws Exception{
//服务端在20006端口监听客户端请求的TCP连接
ServerSocket server = new ServerSocket(20006);
Socket client = null;
boolean f = true;
while(f){
//等待客户端的连接,如果没有获取连接
client = server.accept();
System.out.println("与客户端连接成功!");
//为每个客户端连接开启一个线程
new Thread(new ServerThread(client)).start();
}
server.close();
}
}

ServerThread.java

package sdut.ligong.demo;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class ServerThread implements Runnable {

private Socket client = null;
public ServerThread(Socket client){
this.client = client;
}

@Override
public void run() {
try{
//获取Socket的输出流,用来向客户端发送数据
PrintStream out = new PrintStream(client.getOutputStream());
//获取Socket的输入流,用来接收从客户端发送过来的数据
BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
boolean flag =true;
while(flag){
//接收从客户端发送过来的数据
String str = buf.readLine();
if(str == null || "".equals(str)){
flag = false;
}else{
if("bye".equals(str)){
flag = false;
}else{
//将接收到的字符串前面加上echo,发送到对应的客户端
if (str.contains("1001")&& (str.charAt(4)+"").equals(str.length()+"")) {//接收到请求连接
out.println("1002");
}else{
int endStart = Integer.parseInt(str.substring(str.length()-1));
if (str.contains("1003") && str.length()==Integer.parseInt(str.substring(4,4+endStart))) {

StringBuffer sb = new StringBuffer(str);
out.println(new String(sb.insert(4+endStart, "服务器端回应")));
} else {
out.print("请求失败");
}
}

}
}
}
out.close();
client.close();
}catch(Exception e){
e.printStackTrace();
}
}

}


标签:Socket,编程,TCP,client,println,new,public,out
From: https://blog.51cto.com/u_12606187/5958607

相关文章

  • 使用SocketServer 创建TCP服务端
    **Java能够接受其他通信实体连接请求的类是ServerSocket,如果没有连接,他将一直处于等待状态,线程也被堵塞。ServerSocket包含一个监听来自客户端请求连接的方法。Socke......
  • CubeMX使用FreeRTOS编程指南
    文章目录CubeMX使用FreeRTOS编程指南一、开发前言1.1软件准备1.2开启FreeRTOS二、配置界面三、系统设置2.1调度内核设置2.2内存管理设置2.3钩子函数配置2.5......
  • Linux 防火墙之TCP Wrappers
    1、TCPWrappers 原理Telnet、SSH、FTP、POP和SMTP等很多网络服务都会用到TCPWrapper,它被设计为一个介于外来服务请求和系统服务回应的中间处理软件。  基本处理过......
  • 实验5 结构体应用编程
    实验任务三程序源码1#define_CRT_SECURE_NO_WARNINGS12#include<stdio.h>3#include<string.h>4#include<stdlib.h>5#defineN1006typedefstruct......
  • 网页DOM编程方法(API总结与应用)
    目录网页DOM编程Node、Document和Element三者关系DOM编程常用API总结DOM编程API应用网页DOM编程Node、Document和Element三者关系Node:各种类型的DOMAPI对象会从......
  • golang 范型编程初学
     写了一个批次执行函数的功能,采用范型,直接上代码 batch实现代码:packageutilsimport( "time")typebatch[Tany]struct{ Array[]T Funcfunc(arr......
  • TCP、UDP 网络编程
    TCP、UDP网络编程实验目的1.使用TCP进行套接字通信2.使用UDP进行套接字通信实验原理1.TCP2.UDP3.用到的API(1)intsocket(intdomain,inttype,intprotocol);根......
  • TCP 实现跨平台文件传输
    TCP实现跨平台文件传输实验目的利用TCP完成linux和windows平台的文件传输。实验原理windows与linux上实现tcp文件传输本质上是相同的,只有一些函数调用方式不一......
  • 利用 TCP 完成文件传输的设计
    利用TCP完成文件传输的设计实验目的输入文件路径,利用TCP实现客户文件向服务器的传输,并实现对TCP的基本封装实验原理1.服务器(1)建立socket(2)确定服务器scokaddr_i......
  • 开关量、模拟量、脉冲量分不清楚?PLC最全编程算法详解,看完彻底懂了!
    PLC中无非就是三大量:开关量、模拟量、脉冲量。只在搞清楚三者之间的关系,你就能熟练的掌握PLC了。开关量的计算1、开关量也称逻辑量,指仅有两个取值,0或1、ON或OFF。它是最......