0
点赞
收藏
分享

微信扫一扫

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


注意:先启动服务端,再运行客户端
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();
}
}

}


举报

相关推荐

0 条评论