随笔---HUST计网实验:socket编程

博主大三在读,第一次写随笔,水平有限,就当记录一下学习的过程,顺便面试前复习项目的时候看看。

实验要求:

编写一个 Web 服务器软件,要求如下:

基本要求:

1.可配置 Web 服务器的监听地址、监听端口和主目录(不得写在代码里面,不能每配置一次都要重编译代码);

2.能够单线程处理一个请求。当一个客户(浏览器,如输入

“URL:http:// 202.103.2.3/index.html”)连接时创建一个连接套接字;

3.从连接套接字接收 http 请求报文,并根据请求报文的确定用户请求的网页文件;

4.从服务器的文件系统获得请求的文件。 创建一个由请求的文件组成的 http 响应报文。;

5.经 TCP 连接向请求的浏览器发送响应,浏览器可以正确显示网页的内容;

高级要求:

1.能够传输包含多媒体(如图片)的网页给客户端,并能在客户端正确显示;

2.在服务器端的屏幕上输出请求的来源(IP 地址、端口号和 HTTP 请求命令行);

3.在服务器端的屏幕上能够输出对每一个请求处理的结果;

4.对于无法成功定位文件的请求,根据错误原因,作相应错误提示,并具备一定的异常情况处理能力。

Socket套接字介绍:

Socket 是一个抽象概念,代表了通信双方的端点(Endpoint),通信双方通过 Socket 发送或接收数据。为了将应用程序和底层的网络通信协议屏蔽开来,采用套接字(Socket)这样一个抽象概念来作为应用程序和底层网络之间的应用程序编程接口(API)。因为网络应用程序是进程之间的通信,为了唯一的标识通信对等方的通信进程,套接字必须包含 2 种信息:(1) 通信对等方的网络地址。(2) 通信对等方的进程号,通常叫端口号。

构造方法(常用):ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException。参数port指定服务器要绑定的端口(服务器要监听的端口),参数backlog指定客户连接请求队列的长度,参数bindAddr指定服务器要绑定的IP地址。

java中的Socket类主要包括两个:服务器端ServerSocket和客户端Socket。

系统实现:

实验要求可配置web服务器的监听地址、端口,且不能写在文件里面,因此可以创建一个新的配置文件config.data,内容分两行,包含端口和ip的配置信息,用/结束。

内容如下:

点击查看代码
port:5050/
inetaddr:10.21.207.240/

主类MultiThreadsServer:

public class MultiThreadsServer {
// Main method
public static void main(String[] args) {
int Port_File = 0;//服务器要绑定的端口
int state = 0;
try {
//读取配置文件内容
BufferedReader ConfigReader = new BufferedReader(new FileReader("D:\\新建qq文件保存位置\\netlab1\\netlab1\\src\\config.data"));
String temp_str = "",addr="";//addr:要绑定的ip地址
while ((temp_str = ConfigReader.readLine()) != null) {
if (temp_str.contains("port:")) {
temp_str = temp_str.substring(temp_str.indexOf("port:") + 5, temp_str.indexOf("/")); //每一行以"/"结尾
Port_File = Integer.parseInt(temp_str);
state++;
}
if (temp_str.contains("inetaddr:")) {
temp_str = temp_str.substring(temp_str.indexOf("inetaddr:") + 9, temp_str.indexOf("/"));
addr=temp_str;
state++;
}
if (state == 2)
break; //读取完port和inetaddr就停止,防止文件内容不符合要求
}
// 创建一个server socket
ServerSocket serverSocket = new ServerSocket(Port_File, 10, InetAddress.getByName(addr));
System.out.println("server is listening port:" + serverSocket.getLocalPort());
// 给线程编号
int i = 0;
//用accept()方法监听客户端链接
while (true) {
Socket connectToClient = serverSocket.accept();
// 在控制台上输出连接号
System.out.println("Starting thread " + i);
// 为连接创建一个新的线程
ThreadHandler thread = new ThreadHandler(connectToClient);
// 线程执行
thread.start();
i++;
}
} catch (IOException ex) {
System.err.println(ex);
}
}
}

线程类ThreadHandler:

class ThreadHandler extends Thread {
private Socket connectToClient; // 客户端
public ThreadHandler(Socket socket) {
connectToClient = socket;
}
//实现run()方法
public void run() {
try {
System.out.println("build a link with client:" + connectToClient.getPort());
while (true) {
//从socket建立输入流
InputStream socketInputStream = connectToClient.getInputStream();
// 等待HTTP请求
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//字节数组buffer作为数据缓冲来读取inputstream里面的数据
byte[] buffer = new byte[socketInputStream.available()];//如果网络被阻塞buffer大小为0,未被阻塞则正常接收到
socketInputStream.read(buffer);
String request = new String(buffer);
//如果网络被阻塞,request长度为0,跳过
if (request.length() != 0) {
//输出请求
System.out.println(request);
String firstLineOfRequest = request.substring(0, request.indexOf("\r\n"));
String[] firstLineParts = firstLineOfRequest.split(" ");
String uri = firstLineParts[1];//获取uri
String filename1 = uri.replace("/","");
String filename2 = "D:\\新建qq文件保存位置\\netlab1\\netlab1\\src\\"+filename1;//获取请求的文件名
File file1 = new File(filename2);
//文件不存在的时候,把uri设置为/,实验要求不输入文件名时无法定位的文件中,实际开发一般自动定位到index.html
if(!file1.exists()) uri = "/";
// 定义缺省状态
if (uri.equals("/")) {
uri = "/error.html"; //把缺省状态和无法定位状态放到一起去,少写一个缺省文件
firstLineParts[1] = "/error.html";
System.out.println("查找文件可能不存在");
}
String contentType; //文件类型
if (uri.contains(".html") || uri.contains(".htm")) {
contentType = "text/html";
} else {
if (uri.contains(".jpg") || uri.contains(".jpeg")) {
contentType = "image/jpeg";
} else {
contentType = "text/plain";
}
}
// 报文长度
long file_size = RequestLength("D:\\新建qq文件保存位置\\netlab1\\netlab1\\src\\" + uri); //*
// response result
String responseFirstLine = "HTTP/1.1 200 OK\r\n";
String responseHeader = "Content-Type:" + contentType + "\r\n";
String responseLength = "Content-Length:" + file_size + "\r\n\r\n";
InputStream inputStream = new FileInputStream("D:\\新建qq文件保存位置\\netlab1\\netlab1\\src\\" + uri); //*
OutputStream outputStream = connectToClient.getOutputStream(); //通过客户端获取outputStream
//输出请求处理结果
outputStream.write(responseFirstLine.getBytes());
outputStream.write(responseHeader.getBytes());
outputStream.write(responseLength.getBytes());
System.out.println("Content-length=" + file_size);
System.out.println("uri"+uri);
int len = 0;
byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
// 等待客户接受HTTP响应结果
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// connectToClient.close();
}
} catch (IOException ex) {
System.err.println(ex);
}
}
public static long RequestLength(String filename) {
File file = new File(filename);
if (!file.exists() || !file.isFile()) {
System.out.println("404!Not Found File!");
return -1;
} else
return file.length();
}
}

实验结果:

本地ip(10.21.207.240)+port(5050)+uri(/): 正确显示未定位到

本地ip(10.21.207.240)+port(5050)+uri(/index.html):正确获取

本地ip(10.21.207.240)+port(5050)+uri(/index111.html):对不存在的文件的访问

把电脑和手机连上了同一个ip地址(此时为192.168.43.230),这样就能在手机端显示结果了:

实验要求圆满完成。服务器的文件就用静态文件存放在当前src目录下,如果要使用代码的话记得改文件名称和加自己的文件哦。

HUST-计算机网络实验-socket编程的更多相关文章

  1. 计算机网络实验 UDP套接字编程

    这是个傻瓜式操作教程 西科大计算机网络实验 UDP套接字编程 我用自己的Ubuntu16.04来举例,实验室的是虚拟机,差不多 只针对第三个题目,修改服务器来通过响应客户端发送的GetTime并发送给 ...

  2. socket编程之中的一个:计算机网络基础

    在開始学习网络之前先复习下计算机网络基础吧. 鲁迅说,天下文章一大抄.看你会炒不会炒,基础知识就抄抄书吧. 一 分层模型 1 为什么分层 为了简化网络设计的复杂性.通讯协议採用分层结构.各层协议之间既 ...

  3. 20182332 实验四《Java Socket编程 》实验报告

    20182332 实验肆<数据结构与面向对象程序设计>实验报告 课程:<程序设计与数据结构> 班级: 1823 姓名: 盛国榕 学号:20182332 实验教师:王志强 实验日 ...

  4. TCP和UDP的Socket编程实验

    Linux Socket 函数库是从 Berkeley 大学开发的 BSD UNIX 系统中移植过来的.BSD Socket 接口是在众多 Unix 系统中被广泛支持的 TCP/IP 通信接口,Lin ...

  5. 20184307 实验三 Socket编程技术

    实验三 Socket编程技术 学号 20184307 2019-2020-2 <Python程序设计>实验三报告 课程:<Python程序设计> 班级:1843 姓名:章森洋 ...

  6. 计算机网络|C语言Socket编程,实现两个程序间的通信

    C语言Socket编程,实现两个程序间的通信 server和client通信流程图 在mooc上找到的,使用Socket客户端client和服务端server通信的流程图

  7. 计算机网络(十三),Socket编程实现TCP和UDP

    十三.Socket编程实现TCP和UDP 1.TCP (1)TCPServer.java类 package com.interview.javabasic.socket; import com.int ...

  8. 哈工大 计算机网络 实验二 可靠数据传输协议(停等协议与GBN协议)

    计算机网络实验代码与文件可见github:计算机网络实验整理 实验名称 可靠数据传输协议(停等协议与GBN协议) 实验目的: 本次实验的主要目的. 理解可靠数据传输的基本原理:掌握停等协议的工作原理: ...

  9. 哈工大 计算机网络 实验一 HTTP 代理服务器的设计与实现

    计算机网络实验代码与文件可见github:计算机网络实验整理 实验名称 HTTP 代理服务器的设计与实现 实验目的: 熟悉并掌握 Socket 网络编程的过程与技术:深入理解 HTTP 协议, 掌握 ...

随机推荐

  1. python实现Canny边缘检测

    一,定义与概述 使用图像梯度的算法,在有些场景不适用,如检测大量头发边缘,边缘不够细腻.所以有人提出了Canny算法! 非极大值抑制,保留极大值 参考:https://www.cnblogs.com/ ...

  2. [atARC121D]1 or 2

    对于大小为1的集合,我们可以在其中加入0 因此,枚举0的个数,那么问题即可以看作要求每一个集合大小为2 (特别的,我们允许存在$\{0,0\}$,因为这样删除这两个0显然只会减小极差) 显然此时贪心将 ...

  3. [luogu5387]人形演舞

    先对每一个求sg函数,暴力复杂度为$o(m^{2})$ 取$k$满足$2^{k}\le x<2^{k+1}$(即$x$二进制下的最高位),考虑$y$与$2^{k}$的关系 1.若$1\le y& ...

  4. FastAPI(六十三)实战开发《在线课程学习系统》梳理系统需要接口

    针对上一篇FastAPI(六十二)实战开发<在线课程学习系统>需求分析需求的功能,我们对需要的接口进行梳理,大概的规划出来现有的接口,作为我们第一版的接口的设计出版,然后我们根据设计的接口 ...

  5. 《程序员漫画》| 萌新面试Google

    Hello,大家好.今天的更新有点不一样.我给大家带来了一些程序员漫画.这些都是我自己画的哦.希望大家喜欢. 今天的漫画有简约的画风,也有一些写实的风格(漂亮MM总是有特殊待遇).不知道大家喜欢哪种呢 ...

  6. 洛谷 P6222 - 「P6156 简单题」加强版(莫比乌斯反演)

    原版传送门 & 加强版传送门 题意: \(T\) 组数据,求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^n(i+j)^k\mu^2(\gcd(i,j))\g ...

  7. Atcoder Regular Contest 096 D - Sweet Alchemy(贪心+多重背包)

    洛谷题面传送门 & Atcoder 题面传送门 由于再过 1h 就是 NOI 笔试了所以题解写得会略有点简略. 考虑差分,记 \(b_i=c_i-c_{fa_i}\),那么根据题意有 \(b_ ...

  8. Zabbix源码安装,使用service命令管理zabbix进程

    1.       前期环境: Zabbix源代码解压包:/root/zabbix-3.0.27 Zabbix安装路径:/usr/local/zabbix-3.0.27 2.       复制启动脚本到 ...

  9. Macbook pro进入恢复模式以及无法进入恢复模式解决方案

    看网上很多说用Command+R进入恢复模式,但是,大部分都反馈说,此命令并不能进入恢复模式.我自己也尝试发现了同样问题,最终发现解决方案: 问题出在,[是重新启动电脑,而不是关机+按开机键,否则会造 ...

  10. Linux—&#160;查看系统的位数

    [root@zf-test-web01-4 ~]# file /bin/ls           #"/bin/ls" is a binary file /bin/ls: ELF ...