Java Socket现实简单的HTTP服务
JAVA实现简单的HTTP服务器端

writer.println("Accept-Encoding: gzip, deflate");
writer.println("Host: ");
writer.println("Connection: Keep-Alive");
writer.println();
writer.flush();
String line = reader.readLine();
writer.println("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
writer.println("GET /home.html HTTP/1.1&ln("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*");
java中socket的用法

java中socket的用法Java中的Socket是一种网络通信协议,它可以在不同的计算机之间进行数据传输。
Socket是一种基于TCP/IP协议的网络通信协议,它可以在不同的计算机之间进行数据传输。
在Java中,Socket是一个类,它提供了一种简单的方式来实现网络通信。
Socket的用法在Java中,Socket的用法非常简单。
首先,我们需要创建一个Socket对象。
这个对象可以用来连接到另一个计算机上的Socket 对象。
在创建Socket对象时,我们需要指定要连接的计算机的IP 地址和端口号。
例如,下面的代码创建了一个Socket对象,它连接到IP地址为192.168.1.100,端口号为8080的计算机上:```Socket socket = new Socket("192.168.1.100", 8080);```一旦我们创建了Socket对象,我们就可以使用它来进行数据传输。
在Java中,Socket提供了两个流来进行数据传输:InputStream 和OutputStream。
InputStream用于从Socket中读取数据,而OutputStream用于向Socket中写入数据。
例如,下面的代码从Socket中读取数据:```InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[1024];int len = inputStream.read(buffer);String data = new String(buffer, 0, len);```这个代码片段首先获取了Socket的InputStream对象,然后创建了一个1024字节的缓冲区。
接下来,它调用了InputStream的read()方法来读取数据,并将读取的数据存储在缓冲区中。
最后,它将缓冲区中的数据转换为字符串。
Java Socket现实简单的HTTP服务

Java Socket现实简单的HTTP服务一个简单的用 Java Socket 编写的 HTTP 服务器应用, 演示了请求和应答的协议通信内容以及给客户端返回 HTML 文本和二进制数据文件(一个图片), 同时展示了 404, 200 等状态码.首先运行这个程序,然后打开Web浏览器,键入http://localhost,则这个程序能够显示出浏览器发送了那些信息并且向浏览器返回一个网页和一副图片, 并测试同浏览器对话. 当浏览器看到 HTML 中带有图片地址时, 则会发出第二次连接来请求图片等资源. 这个例子可以帮您理解 Java 的 HTTP 服务器软件是基于 J2SE 的 Socket 等软件编写的概念, 并熟悉HTTP 协议. 相反的用 Telnet 连接到已有的服务器则可以帮忙理解浏览器的运行过程和服务器端的返回内容.当用户在Web浏览器地址栏中输入一个带有http://前缀的URL并按下Enter 后,或者在Web页面中某个以http://开头的超链接上单击鼠标,HTTP事务处理的第一个阶段--建立连接阶段就开始了.HTTP的默认端口是80. 随着连接的建立,HTTP就进入了客户向服务器发送请求的阶段.客户向服务器发送的请求是一个有特定格式的ASCII消息,其语法规则为:< Method > < URL > < HTTP Version > <\r\n>{ <Header>:<Value> <\r\n>}<\r\n>{ Entity Body }请求消息的顶端是请求行,用于指定方法,URL和HTTP协议的版本,请求行的最后是回车换行.方法GET,POST,HEAD,PUT,DELETE等. 在请求行之后是若干个报头(Header)行.每个报头行都是由一个报头和一个取值构成的二元对,报头和取值之间以":"分隔;报头行的最后是回车换行.常见的报头有Accept(指定MIME 媒体类型),Accept_Charset(响应消息的编码方式),Accept_Encoding(响应消息的字符集),User_Agent(用户的浏览器信息)等. 在请求消息的报头行之后是一个回车换行,表明请求消息的报头部分结束.在这个之后是请求消息的消息实体(Entity Body).具体的例子参看httpRe q uest.t x t.Web服务器在收到客户请求并作出处理之后,要向客户发送应答消息.与请求消息一样,应答消息的语法规则为:< HTTP Version> <Status Code> [<Message>]<\r\n>{ <Header>:<Value> <\r\n> }<\r\n>{ Entity Body }应答消息的第一行为状态行,其中包括了HTTP版本号,状态码和对状态码进行简短解释的消息;状态行的最后是回车换行.状态码由3位数字组成,有5类:参看:HTTP应答码及其意义1XX保留2XX 表示成功3XX 表示URL已经被移走4XX 表示客户错误5XX 表示服务器错误例如:415,表示不支持改媒体类型;503,表示服务器不能访问.最常见的是200,表示成功.常见的报头有:Last_Modi f ied(最后修改时间),Content_Type(消息内容的MIME类型),Content_Length(内容长度)等.在报头行之后也是一个回车换行,用以表示应答消息的报头部分的结束,以及应答消息实体的开始.下面是一个应答消息的例子:HTTP/1.0 200 O KDate: Moday,07-Apr-97 21:13:02 GMTServer:N CSA/1.1MIME_Version:1.0Content_Type:te x t/ht m lLast_Modi f ied:Thu Dec 5 09:28:011996Coentent_Length:3107<HTML><HEAD><TITLE></HTML>在用Java语言实现HTTP服务器时,首先启动一个j .ServerSocket在提供服务的端口上监听连接.向客户返回文本时,可以用 PrintWriter,但是如果返回二进制数据,则必须使用OutputStrea m.w rite(byte[])方法,返回的应答消息字符串可以使用 String.getBytes()方法转换为字节数组返回,或者使用PrintStrea m 的print()方法写入文本,用 w rite(byte[])方法写入二进制数据.源程序来自/m yeclipse_j ava,本程序是在原有基础上进行了一些调整,源程序在POST请求时会阻塞,本程序解决了此问题,另外,本程序在原有的基础上增加了文件上传与下载模拟功能:Java代码i m port j ava.io.F ile;i m port j ava.io.F ileInputStrea m;1.i m port j ava.io.IOE x ception;2.i m port j ava.io.InputStrea m;3.i m port j ava.io.PrintStrea m;4.i m port j ava.io.PrintWriter;5.i m port j .ServerSocket;6.i m port j .Socket;7.i m port j .URLDecoder;8.i m port j ava.util.ArrayList;9.i m port j ava.util.StringTokeni z er;10.11./**12. *13. *@author 刘长炯14. *m odi by jzj15. *16. */17.public class Si m pleHttpServer i m ple m ents Runnable {18.19. ServerSocket serverSocket;//服务器Socket20.21. public static int PORT =80;//标准HTTP端口22.23. public String encoding = "GB K";24.25. public Si m pleHttpServer() {26. try {27. serverSocket = ne w ServerSocket(PORT);28. } catch (E x ception e) {29. e.printStackTrace();30. Syste m.e x it(1);31. }ne w Thread(this).start();Syste m.out.println("HTTP服务器正在运行,端口:" + PORT);32. }33.34. public void run() {35. w hile (true) {36. try {37. Socket client = serverSocket.accept();//客户机(这里是 IE 等浏览器)已经连接到当前服务器38. i f (client != null) {39. Syste m.out.println("连接到服务器的用户:" + client);40. try {41. // 第一阶段: 打开输入流42. InputStrea m is = client.getInputStrea m();43.44. Syste m.out.println("客户端发送的请求信息: >>>>>>>>>>>>>>>>>>>>>>>>>");45. // 读取第一行, 请求地址46. String line = readLine(is, 0);47. //打印请求行48. Syste m.out.print(line);49. // < Method > < URL > < HTTP Version > <\r\n> 取的是URL部分50. String resource = line.substring(line.inde x O f('/'), line51. .lastInde x O f('/') - 5);52. //获得请求的资源的地址53. resource = URLDecoder.decode(resource, encoding);//反编码 URL 地址54. String m ethod = ne w StringTokeni z er(line).ne x tEle m ent()55. .toString();// 获取请求方法, GET 或者 POST56. int contentLength =0;//如果为POST方法,则会有消息体长度57.58. // 读取所有浏览器发送过来的请求参数头部信息59. do {60. line = readLine(is, 0);61. //如果有Content-Length消息头时取出62. i f (line.startsWith("Content-Length")) {63. contentLength = Integer.parseInt(line.split(":")[1]64. .tri m());65. }66. //打印请求部信息67. Syste m.out.print(line);68. //如果遇到了一个单独的回车换行,则表示请求头结束69. } w hile (!line.e q uals("\r\n"));70. //如果是POST请求,则有请求体71. i f ("POST".e q ualsIgnoreCase(m ethod)) {72. //注,这里只是简单的处理表单提交的参数,而对于上传文件这里是不能这样处理的,73. //因为上传的文件时消息体不只是一行,会有多行消息体74. Syste m.out.print(readLine(is, contentLength));75. Syste m.out.println();76. }77.78. Syste m.out.println("客户端发送的请求信息结束 <<<<<<<<<<<<<<<<<<<<<<<<<<");79. Syste m.out.println("用户请求的资源是:" + resource);80. Syste m.out.println("请求的类型是: " +m ethod);81. Syste m.out.println();82.83. //如果是下载文件84. i f (resource.startsWith("/do w nload")) {85. f ileDo w nload("test.t x t", client);86. closeSocket(client);87. continue;88. }89.90. // GI F 图片就读取一个真实的图片数据并返回给客户端91. i f (resource.endsWith(".gi f")) {92. i m gDo w nload("test.gi f", client);93. closeSocket(client);94. continue;95. }96.97. // 请求 JPG 格式就报错 40498. i f (resource.endsWith(".j pg")) {99. PrintWriter out = ne w PrintWriter(client.getOutputStrea m(),100. true);101. out.println("HTTP/1.0 404 N ot f ound");//返回应答消息,并结束应答102. out.println();// 根据 HTTP 协议, 空行将结束头信息103. out.close();104. closeSocket(client);105. continue;106. } else {107. // 用 w riter 对客户端 socket 输出一段 HTML 代码108. PrintWriter out = ne w PrintWriter(client.getOut putStrea m(),109. true);110. out.println("HTTP/1.0 200 O K");//返回应答消息,并结束应答111. out.println("Content-Type:te x t/ht m l;charset="+ encoding);112. out.println();// 根据 HTTP 协议, 空行将结束头信息113.114. out.println("<h1> Hello Http Server</h1>"); 115. out.println("你好, 这是一个 Java HTTP 服务器 de m o 应用.<br>");116. out.println("您请求的路径是: " + resource + "<br >");117. out.println("你请求的页面含有图片:<i m g src='tes t.gi f'><br>"118.+ "<a hre f='test.gi f'>手动点击打开test.gi f 图片文件.</a>");119. out.println("<br>服务器不支持j pg格式图片,所以显示XX:"120.+ "<i m g src='test.j pg'><br><a hre f='test.j pg'>"121.+ "手动点击打开test.j pg,会跳转另一页面,并且服务返回为404错误</a><br>");122. out123. .println("<f or m m ethod=post action='/pat h?q ryPar m=POST URL查询参数' > POST 表单 "124.+ "<input na m e=userna m e value='用户'> "125.+ "<input na m e=sub m it type=sub m i t value=sub m it></f or m>");126. out127. .println("<f or m m ethod=get action='/path ?q ryPar m=GET URL查询参数' > GET 表单 "128.+ "<input na m e=userna m e value='用户'> "129.+ "<input na m e=sub m it type=sub m i t value=sub m it></f or m>");130.131. out132. .println("<f or m m ethod=post action='/pat h?q ryPar m=POST URL查询参数'"133.+ " enctype='m ultipart/f or m-data' >"134.+ "文件上传 <input type='f ile' na m e=f ile1 ><br>"135.+ " &nbs p; "136.+ "<input type='f ile' na m e=f ile2 ><b r>"137.+ " &nbs p; "138.+ "<input na m e=userna m e value='用户'> "139.+ "<input na m e=sub m it type=sub m i t value=sub m it></f or m>");140. out.println("<a hre f='/do w nload'>点击此处模拟文件下载</a>");141.142. out.close();143.144. closeSocket(client);145. }146. } catch (E x ception e) {147. Syste m.out.println("HTTP服务器错误:" + e.getLoca li z edMessage());148. }149. }150. //Syste m.out.println(client+"连接到HTTP服务器");//如果加入这一句,服务器响应速度会很慢151. } catch (E x ception e) {152. Syste m.out.println("HTTP服务器错误:" + e.getLocali z ed Message());153. }154. }155. }156.157. /*158.* 这里我们自己模拟读取一行,因为如果使用API中的Bu ff eredReader时,它是读取到一个回车换行后159.*才返回,否则如果没有读取,则一直阻塞,这就导致如果为POST 请求时,表单中的元素会以消息体传送,160.* 这时,消息体最末按标准是没有回车换行的,如果此时还使用Bu ff eredReader来读时,则POST提交161.* 时会阻塞。
Java实现http代理服务器

Java实现http代理服务器 Java实现http代理服务器本⽂连接:gitee:默认端⼝:8888javac RuphyHttpProxy.javajava RuphyHttpProxy 11111代码如下://package me.muphy.servicce;import java.io.Closeable;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import .ServerSocket;import .Socket;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;import java.util.regex.Matcher;import java.util.regex.Pattern;/*** http代理*/public class RuphyHttpProxy extends Thread {private final ServerSocket server;private final int port;public RuphyHttpProxy(int port) throws IOException {this.port = port;server = new ServerSocket(port);System.out.println("代理端⼝:" + this.port);}public static void main(String[] args) throws IOException {int port = 8888;if (args != null && args.length > 0 && args[0].matches("\\d+")) {port = Integer.parseInt(args[0]);}new RuphyHttpProxy(port).start();}@Overridepublic void run() {// 线程运⾏函数while (true) {try {Socket client = server.accept();//使⽤线程处理收到的请求new HttpConnectThread(client).start();} catch (Exception e) {e.printStackTrace();}}}/*** 新连接处理线程*/private static class HttpConnectThread extends Thread {private Socket client;private Socket server = null;private String host = null;private int port = 80;private int clientReadLength = 0;byte clientInputBuffer[] = new byte[1024 * 1024 * 4];private DataInputStream clientInputStream = null; //客户端输⼊流private DataInputStream serverInputStream = null; //服务端输⼊流private DataOutputStream clientOutputStream = null; //客户端输出流private DataOutputStream serverOutputStream = null; //服务端输出流private long createTime = System.currentTimeMillis();private String clientInputString = null;public HttpConnectThread(Socket client) {this.client = client;}@Overridepublic void run() {try {clientInputStream = new DataInputStream(client.getInputStream());clientOutputStream = new DataOutputStream(client.getOutputStream());if (clientInputStream != null && clientOutputStream != null) {clientReadLength = clientInputStream.read(clientInputBuffer, 0, clientInputBuffer.length); // 从客户端读数据if (clientReadLength > 0) { // 读到数据clientInputString = new String(clientInputBuffer, 0, clientReadLength);if (clientInputString.contains("\n")) {clientInputString = clientInputString.substring(0, clientInputString.indexOf("\n"));}if (clientInputString.contains("CONNECT ")) {parseServerHost("CONNECT ([^ ]+) HTTP/");} else if (clientInputString.contains("http://") && clientInputString.contains("HTTP/")) {// 从所读数据中取域名和端⼝号parseServerHost("http://([^/]+)/");}if (host != null) {server = new Socket(host, port);// 根据读到的域名和端⼝号建⽴套接字serverInputStream = new DataInputStream(server.getInputStream());serverOutputStream = new DataOutputStream(server.getOutputStream());if (serverInputStream != null && serverOutputStream != null && server != null) {if (clientInputString.contains("CONNECT ")) {doConnect();return;}doRequest();return;}}}} catch (Exception e) {e.printStackTrace();}IOUtils.close(serverInputStream, serverOutputStream, server, clientInputStream, clientOutputStream, client);}/*** 解析主机地址** @param regExp*/private void parseServerHost(String regExp) {Pattern pattern = pile(regExp);Matcher matcher = pattern.matcher(clientInputString + "/");if (matcher.find()) {host = matcher.group(1);if (host.contains(":")) {port = Integer.parseInt(host.substring(host.indexOf(":") + 1));host = host.substring(0, host.indexOf(":"));}}}/*** 处理请求** @throws IOException*/private void doRequest() throws IOException, InterruptedException {serverOutputStream.write(clientInputBuffer, 0, clientReadLength);serverOutputStream.flush();final CountDownLatch latch;if (clientInputString.contains("POST ")) {latch = new CountDownLatch(2);// 建⽴线程 , ⽤于从内⽹读数据 , 并返回给外⽹new HttpChannel(clientInputStream, serverOutputStream, latch).start();} else {latch = new CountDownLatch(1);}// 建⽴线程 , ⽤于从外⽹读数据 , 并返回给内⽹new HttpChannel(serverInputStream, clientOutputStream, latch).start();latch.await(120, TimeUnit.SECONDS);IOUtils.close(serverInputStream, serverOutputStream, server, clientInputStream, clientOutputStream, client);System.out.println("请求地址:" + clientInputString + ",耗时:" + (System.currentTimeMillis() - createTime) + "ms"); }/*** 处理连接请求** @return*/private void doConnect() throws IOException, InterruptedException {String ack = "HTTP/1.0 200 Connection established\r\n";ack = ack + "Proxy-agent: proxy\r\n\r\n";clientOutputStream.write(ack.getBytes());clientOutputStream.flush();final CountDownLatch latch = new CountDownLatch(2);// 建⽴线程 , ⽤于从外⽹读数据 , 并返回给内⽹new HttpChannel(serverInputStream, clientOutputStream, latch).start();// 建⽴线程 , ⽤于从内⽹读数据 , 并返回给外⽹new HttpChannel(clientInputStream, serverOutputStream, latch).start();latch.await(120, TimeUnit.SECONDS);IOUtils.close(serverInputStream, serverOutputStream, server, clientInputStream, clientOutputStream, client);}}/*** 流通道处理线程*/private static class HttpChannel extends Thread {private final CountDownLatch countDownLatch;private final DataInputStream in;private final DataOutputStream out;public HttpChannel(DataInputStream in, DataOutputStream out, CountDownLatch countDownLatch) {this.in = in;this.out = out;this.countDownLatch = countDownLatch;}@Overridepublic void run() {byte buf[] = new byte[10240];try {while ((len = in.read(buf, 0, buf.length)) != -1) { out.write(buf, 0, len);out.flush();}} catch (Exception e) {e.printStackTrace();} finally {IOUtils.close(in, out);countDownLatch.countDown();}}}/*** 流⼯具类*/private static class IOUtils {/*** 关闭所有流*/private static void close(Closeable... closeables) {if (closeables != null) {for (int i = 0; i < closeables.length; i++) {if (closeables[i] != null) {try {closeables[i].close();} catch (IOException e) {e.printStackTrace();}}}}}}}。
Java基于Socket实现HTTP下载客户端

Java基于Socket实现HTTP下载客户端没有借助任何第三⽅库,完全基于JAVA Socket实现⼀个最⼩化的HTTP⽂件下载客户端。
完整的演⽰如何通过Socket实现下载⽂件的HTTP请求(request header)发送如何从Socket中接受HTTP响应(Response header, Response body)报⽂并解析与保存⽂件内容。
如何通过SwingWork实现UI刷新,实时显⽰下载进度。
⾸先看⼀下UI部分:【添加下载】按钮:点击弹出URL输⼊框,⽤户Copy要下载⽂件URL到输⼊框以后,点击[OK]按钮即开始下载【清除完成】按钮:清除所有已经下载完成的⽂件列表⽂件下载状态分为以下⼏种:package com.gloomyfish.socket.tutorial.http.download;public enum DownLoadStatus {NOT_STARTED,IN_PROCESS,COMPLETED,ERROR}UI部分主要是利⽤Swing组件完成。
点击【添加下载】执⾏的代码如下:final JDialog dialog = new JDialog(this,"Add File Link",true);dialog.getContentPane().setLayout(new BorderLayout());// dialog.setSize(new Dimension(400,200));final URLFilePanel panel = new URLFilePanel();panel.setUpListener(new ActionListener(){@Overridepublic void actionPerformed(ActionEvent e) {if("OK".equals(e.getActionCommand())){if(panel.validateInput()) {DownloadDetailStatusInfoModel data = new DownloadDetailStatusInfoModel(panel.getValidFileURL());tableModel.getData().add(data);startDownlaod();refreshUI();}dialog.setVisible(false);dialog.dispose();} else if("Cancel".equals(e.getActionCommand())) {dialog.setVisible(false);dialog.dispose();}}});dialog.getContentPane().add(panel, BorderLayout.CENTER);dialog.pack();centre(dialog);dialog.setVisible(true);【清除完成】按钮执⾏的代码如下:private void clearDownloaded() {List<DownloadDetailStatusInfoModel> downloadedList = new ArrayList<DownloadDetailStatusInfoModel>();for(DownloadDetailStatusInfoModel fileStatus : tableModel.getData()) {if(fileStatus.getStatus().toString().equals(PLETED.toString())) {downloadedList.add(fileStatus);}}tableModel.getData().removeAll(downloadedList);refreshUI();}让JFrame组件居中显⽰的代码如下:public static void centre(Window w) {Dimension us = w.getSize();Dimension them = Toolkit.getDefaultToolkit().getScreenSize();int newX = (them.width - us.width) / 2;int newY = (them.height - us.height) / 2;w.setLocation(newX, newY);}HTTP协议实现部分:概述:HTTP请求头与相应头报⽂基本结构与解释HTTP请求:⼀个标准的HTTP请求报⽂如其中请求头可以有多个,message-body可以没有,不是必须的。
Java Socket应答与HTTP服务器的关系.doc

Java Socket应答与HTTP效劳器的关系Java Socket应答一直伴随着我们的编程生活,在不断的开展中有很多知识需要我们学习。
下面我们就先来看看有关Java Socket应答的代码,有点长,但是看下去就会让你豁然开朗。
/1.1表示这个效劳器是1.1版,200是效劳器对客户请求的应答状态码,OK是对应答状态码的解释,之后是这个文档的元信息和文档正文。
(相关应答状态码和元信息的解释请参阅Ir标准草案:RFC2616)。
1.Http.java2.import java..*;3.import java.io.*;4.import java.util.Properties;5.import java.util.Enumeration;6.public class Http {7.protected Socket client;8.protected BufferedOutputStream sender;9.protected BufferedInputStream receiver;10.protected ByteArrayInputStream byteStream;11.protected URL target;12.private int responseCode=-1;13.private String responseMessage="";14.private String serverVersion="";15.private Properties header = new Properties();16.public Http() { }17.public Http(String url) {18.GET(url) ;19.}20./* GET方法根据URL,会请求文件、数据库查询结果、程序运行结果等多种内容 */21.public void GET(String url) {22.try {23.check(url);24.openServer(target.getHost(),target.getPort() );25.String cmd = "GET "+ getURLFormat(target) +"/1.0\r\n"26.+ getBaseHeads()+"\r\n";27.sendMessage(cmd);28.receiveMessage();29.} catch(ProtocolException p) {30.p.printStackTrace();31.return;32.} catch(UnknownHostException e) {33.e.printStackTrace();34.return;35.} catch(IOException i) {36.i.printStackTrace();37.return;38.}39.}40./*41.* HEAD方法只请求URL的元信息,不包括URL本身。
Java实现HTTP代理服务器
Java实现HTTP代理服务器Java 实现HTTP代理服务器1. 主服务,⽤来侦听端⼝:package org.javaren.proxy;import .ServerSocket;import .Socket;publicclassSocketProxy{/*** @param args*/publicstaticvoid main(String[] args)throwsException{ServerSocket serverSocket =newServerSocket(8888);while(true){Socket socket =null;try{socket = serverSocket.accept();newSocketThread(socket).start();}catch(Exception e){e.printStackTrace();}}}}2. 核⼼代码,处理链接的代理线程,内部设计了Socket的认证:package org.javaren.proxy;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .Socket;publicclassSocketThreadextendsThread{privateSocket socketIn;privateInputStream isIn;privateOutputStream osIn;//privateSocket socketOut;privateInputStream isOut;privateOutputStream osOut;publicSocketThread(Socket socket){this.socketIn = socket;}privatebyte[] buffer =newbyte[4096];privatestaticfinalbyte[] VER ={0x5,0x0};privatestaticfinalbyte[] CONNECT_OK ={0x5,0x0,0x0,0x1,0,0,0,0,0,0};publicvoid run(){try{System.out.println("\n\na client connect "+ socketIn.getInetAddress()+":"+ socketIn.getPort());isIn = socketIn.getInputStream();osIn = socketIn.getOutputStream();int len = isIn.read(buffer);System.out.println("< "+ bytesToHexString(buffer,0, len));osIn.write(VER);osIn.flush();System.out.println("> "+ bytesToHexString(VER,0, VER.length));len = isIn.read(buffer);System.out.println("< "+ bytesToHexString(buffer,0, len));// 查找主机和端⼝String host = findHost(buffer,4,7);int port = findPort(buffer,8,9);System.out.println("host="+ host +",port="+ port);socketOut =newSocket(host, port);isOut = socketOut.getInputStream();osOut = socketOut.getOutputStream();//for(int i =4; i <=9; i++){CONNECT_OK[i]= buffer[i];}osIn.write(CONNECT_OK);osIn.flush();System.out.println("> "+ bytesToHexString(CONNECT_OK,0, CONNECT_OK.length));SocketThreadOutputout=newSocketThreadOutput(isIn, osOut); out.start();SocketThreadInputin=newSocketThreadInput(isOut, osIn);in.start();out.join();in.join();}catch(Exception e){System.out.println("a client leave");}finally{try{if(socketIn !=null){socketIn.close();}}catch(IOException e){e.printStackTrace();}}System.out.println("socket close");}publicstaticString findHost(byte[] bArray,intbegin,intend){StringBuffer sb =newStringBuffer();for(int i =begin; i <=end; i++){sb.append(Integer.toString(0xFF& bArray[i]));sb.append(".");}sb.deleteCharAt(sb.length()-1);return sb.toString();}publicstaticint findPort(byte[] bArray,intbegin,intend){int port =0;for(int i =begin; i <=end; i++){port <<=16;port += bArray[i];}return port;}// 4A 7D EB 69// 74 125 235 105publicstaticfinalString bytesToHexString(byte[] bArray,intbegin,intend){ StringBuffer sb =newStringBuffer(bArray.length);String sTemp;for(int i =begin; i <end; i++){sTemp =Integer.toHexString(0xFF& bArray[i]);if(sTemp.length()<2)sb.append(0);sb.append(sTemp.toUpperCase());sb.append(" ");}return sb.toString();}}3. 读取线程,负责外⾯读数据,写⼊到请求端:package org.javaren.proxy;/*** * 从外部读取,向内部发送信息*/import java.io.InputStream;import java.io.OutputStream; publicclassSocketThreadInputextendsThread{privateInputStream isOut;privateOutputStream osIn;publicSocketThreadInput(InputStream isOut,OutputStream osIn){this.isOut = isOut;this.osIn = osIn;}privatebyte[] buffer =newbyte[409600];publicvoid run(){try{int len;while((len = isOut.read(buffer))!=-1){if(len >0){System.out.println(newString(buffer,0, len));osIn.write(buffer,0, len);osIn.flush();}}}catch(Exception e){System.out.println("SocketThreadInput leave");}}}4. 写⼊线程,负责读取请求端数据,写⼊到⽬标端:package org.javaren.proxy;import java.io.InputStream;import java.io.OutputStream;/*** 从内部读取,向外部发送信息** @author zxq**/publicclassSocketThreadOutputextendsThread{privateInputStream isIn;privateOutputStream osOut;publicSocketThreadOutput(InputStream isIn,OutputStream osOut){ this.isIn = isIn;this.osOut = osOut;}privatebyte[] buffer =newbyte[409600];publicvoid run(){try{int len;while((len = isIn.read(buffer))!=-1){if(len >0){System.out.println(newString(buffer,0, len));osOut.write(buffer,0, len);osOut.flush();}}}catch(Exception e){System.out.println("SocketThreadOutput leave");}}}。
socket,实现http协议
socket,实现http协议篇一:用Socket类实现HTTP协议客户端应用用Socket类实现HTTP协议客户端应用Http客户端程序已集成在Java语言中,可以通过URLConnection类调用。
遗憾的是,由于SUN没有公布Http客户程序的源码,它实现的细节仍是一个谜。
本文根据HTTP 协议规范,用.Socket类实现一个HTTP协议客户端程序。
1.Socket类:了解TCP/IP协议集通信的读者知道,协议间的通信是通过Socket完成的。
在包中,Socket类就是对Socket的具体实现。
它通过连接到主机后,返回一个I/O流,实现协议间的信息交换。
2 . HTTP协议HTTP协议同其它TCP/IP协议集中的协议一样,是遵循客户/服务器模型工作的。
客户端发往服务端的信息格式如下: ------------------------------请求方法URL HTTP协议的版本号提交的元信息**空行**实体------------------------------请求方法是对这次连接工作的说明,目前HTTP协议已经发展到1.1版,它包括GET、HEAD、POST、DELETE、OPTIONS、TRACE、PUT 七种。
元信息是关于当前请求的信息。
通过分析元信息,可以检查实体数据是否完整,接收过程是否出错,类型是否匹配等。
元信息的引入使HTTP协议通信更加稳妥可靠。
实体是请求的具体内容。
将上述报文发往Web服务器,如果成功,应答格式如下:--------------------------------HTTP协议的版本号应答状态码应答状态码说明接收的元信息**空行**实体--------------------------------以上报文发向客户端,并且接收成功,彼此间关闭连接,完成一次握手。
下面用最常用的GET方法,来说明具体的报文应用----------------------------------GET HTTP/1.0 accept: www/source; text/html; image/gif; image/jpeg; */* User_Agent: myAgent**空行**-----------------------------------这个报文是向主机请求一个缺省HTML文档。
Java之利用OkHttpClient进行简单的http请求,利用Jackson框架把js。。。
Java之利⽤OkHttpClient进⾏简单的http请求,利⽤Jackson框架把js。
⼆.代码java类:public class Transaction { //使⽤了静态的内部类public static class Output{String address;long amount;public String getAddress() {return address;}public long getAmount() {return amount;}public void setAddress(String address) {this.address = address;}public void setAmount(long amount) {this.amount = amount;}@Overridepublic String toString() {return "Output{" +"address='" + address + '\'' +", amount=" + amount +'}';}}private String txid;private String action;private long amount;private long fees;private long time;private int confirmations;private List<Output> outputs;public void setTxid(String txid) {this.txid = txid;}public void setAction(String action) {this.action = action;}public void setAmount(long amount) {this.amount = amount;}public void setFees(long fees) {this.fees = fees;}public void setTime(long time) {this.time = time;}public void setConfirmations(int confirmations) {this.confirmations = confirmations;}public String getTxid() {return txid;}public void setOutputs(List<Output> outputs) {this.outputs = outputs;}@Overridepublic String toString() {return "Transaction{" +"txid='" + txid + '\'' +", action='" + action + '\'' +", amount=" + amount +", fees=" + fees +", time=" + time +", confirmations=" + confirmations +", outputs=" + outputs +'}';}}http请求:public class HttpClient {public static final MediaType JSON = MediaType.parse("application/json;charset=utf-8");public static String httpGet(String url) throws IOException {OkHttpClient httpClient = new OkHttpClient();Request request = new Request.Builder().url(url).build();Response response = httpClient.newCall(request).execute();return response.body().string(); // 返回的是string 类型,json的mapper可以直接处理}public static String httpPost(String url, String json) throws IOException {OkHttpClient httpClient = new OkHttpClient();RequestBody requestBody = RequestBody.create(JSON, json);Request request = new Request.Builder().url(url).post(requestBody).build();Response response = httpClient.newCall(request).execute();return response.body().string();}}json转化:public Transaction[] getTransaction(int skip,int limit){String txHistoryUrl = String.format("%s%s?skip=%d&limit=%d",url,TX_HISTORY,skip,limit); //url 后边的参数是业务规定,格式可以参考,具体可以⾃定义System.out.println(txHistoryUrl);try{String newTx = HttpClient.httpGet(txHistoryUrl);System.out.println(newTx);ObjectMapper mapper = new ObjectMapper(); // 只需要⼀个mapper就可以实现return mapper.readValue(newTx,Transaction[].class);}catch (IOException e){e.printStackTrace();}return null;}json数据如下:[{"txid":"ad416e1b4b8b807b4a0946affb17cf253c1af7a7e6c6a9e21fac2e93b2c88746","action":"received","amount":10000,"fees":3800,"time":1486111663,"confirmations":179,"outputs":[{"amount":10000,"address":"2MxDyD4idPv8LqYNP4Aq4QExR 三.问题解决Json错误:Can not deserialize instance of xx out of START_ARRAY tokenServer这个可能是后台返回的是数组类型的json,所以transaction要⽤数组return mapper.readValue(newTx,Transaction[].class);json错误:No suitable constructor found for type [xxxx]: can not instantiate from JSON object (need to add/enable type information?) at xxx这个需要java class中的内部类使⽤静态类,见transaction类中的output内部类。
Java实现简易的socket程序(能运行!)
利用Java实现简易的Socket程序步骤:1.新建两个类2.先启动MyServer,再启动MyClient服务端MyServer:import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .ServerSocket;import .Socket;public class MyServer {public static void main(String[] args) throws IOException {//绑定服务端口,暴露了一个服务,服务地址:本机IP+9999ServerSocket server = new ServerSocket(9999);Socket socket = server.accept();System.out.println("与客户端连接成功");//服务端向客户端发送消息OutputOutputStream out = socket.getOutputStream();String info = "hello";//String ->byte[]out.write(info.getBytes());//接收客户端消息InputStream in = socket.getInputStream();byte[] bs = new byte[100];in.read(bs);//byte[]->StringSystem.out.println("接收到客户端发来的消息为:"+new String(bs));}}客户端MyClient:import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .Socket;public class MyClient {public static void main(String[] args) throws IOException {//客户端连接Server发布的服务Socket socket = new Socket("127.0.0.1",9999);//接收服务端发送的消息InputStreamInputStream in = socket.getInputStream();byte[] bs = new byte[100];in.read(bs);//byte[]->StringSystem.out.println("client接收到的消息为:"+new String(bs));//客户端作出反馈OutputStream out = socket.getOutputStream();out.write("world".getBytes());}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Java Socket现实简单的HTTP服务一个简单的用 Java Socket 编写的 HTTP 服务器应用, 演示了请求和应答的协议通信内容以及给客户端返回 HTML 文本和二进制数据文件(一个图片), 同时展示了 404, 200 等状态码.首先运行这个程序,然后打开Web浏览器,键入http://localhost,则这个程序能够显示出浏览器发送了那些信息并且向浏览器返回一个网页和一副图片, 并测试同浏览器对话. 当浏览器看到 HTML 中带有图片地址时, 则会发出第二次连接来请求图片等资源. 这个例子可以帮您理解 Java 的 HTTP 服务器软件是基于 J2SE 的 Socket 等软件编写的概念, 并熟悉HTTP 协议. 相反的用 Telnet 连接到已有的服务器则可以帮忙理解浏览器的运行过程和服务器端的返回内容.当用户在Web浏览器地址栏中输入一个带有http://前缀的URL并按下Enter 后,或者在Web页面中某个以http://开头的超链接上单击鼠标,HTTP事务处理的第一个阶段--建立连接阶段就开始了.HTTP的默认端口是80. 随着连接的建立,HTTP就进入了客户向服务器发送请求的阶段.客户向服务器发送的请求是一个有特定格式的ASCII消息,其语法规则为:< Method > < URL > < HTTP Version > <\r\n>{ <Header>:<Value> <\r\n>}<\r\n>{ Entity Body }请求消息的顶端是请求行,用于指定方法,URL和HTTP协议的版本,请求行的最后是回车换行.方法GET,POST,HEAD,PUT,DELETE等. 在请求行之后是若干个报头(Header)行.每个报头行都是由一个报头和一个取值构成的二元对,报头和取值之间以":"分隔;报头行的最后是回车换行.常见的报头有Accept(指定MIME 媒体类型),Accept_Charset(响应消息的编码方式),Accept_Encoding(响应消息的字符集),User_Agent(用户的浏览器信息)等. 在请求消息的报头行之后是一个回车换行,表明请求消息的报头部分结束.在这个之后是请求消息的消息实体(Entity Body).具体的例子参看httpRe q uest.t x t.Web服务器在收到客户请求并作出处理之后,要向客户发送应答消息.与请求消息一样,应答消息的语法规则为:< HTTP Version> <Status Code> [<Message>]<\r\n>{ <Header>:<Value> <\r\n> }<\r\n>{ Entity Body }应答消息的第一行为状态行,其中包括了HTTP版本号,状态码和对状态码进行简短解释的消息;状态行的最后是回车换行.状态码由3位数字组成,有5类:参看:HTTP应答码及其意义1XX保留2XX 表示成功3XX 表示URL已经被移走4XX 表示客户错误5XX 表示服务器错误例如:415,表示不支持改媒体类型;503,表示服务器不能访问.最常见的是200,表示成功.常见的报头有:Last_Modi f ied(最后修改时间),Content_Type(消息内容的MIME类型),Content_Length(内容长度)等.在报头行之后也是一个回车换行,用以表示应答消息的报头部分的结束,以及应答消息实体的开始.下面是一个应答消息的例子:HTTP/1.0 200 O KDate: Moday,07-Apr-97 21:13:02 GMTServer:N CSA/1.1MIME_Version:1.0Content_Type:te x t/ht m lLast_Modi f ied:Thu Dec 5 09:28:011996Coentent_Length:3107<HTML><HEAD><TITLE></HTML>在用Java语言实现HTTP服务器时,首先启动一个j .ServerSocket在提供服务的端口上监听连接.向客户返回文本时,可以用 PrintWriter,但是如果返回二进制数据,则必须使用OutputStrea m.w rite(byte[])方法,返回的应答消息字符串可以使用 String.getBytes()方法转换为字节数组返回,或者使用PrintStrea m 的print()方法写入文本,用 w rite(byte[])方法写入二进制数据.源程序来自/m yeclipse_j ava,本程序是在原有基础上进行了一些调整,源程序在POST请求时会阻塞,本程序解决了此问题,另外,本程序在原有的基础上增加了文件上传与下载模拟功能:Java代码i m port j ava.io.F ile;i m port j ava.io.F ileInputStrea m;1.i m port j ava.io.IOE x ception;2.i m port j ava.io.InputStrea m;3.i m port j ava.io.PrintStrea m;4.i m port j ava.io.PrintWriter;5.i m port j .ServerSocket;6.i m port j .Socket;7.i m port j .URLDecoder;8.i m port j ava.util.ArrayList;9.i m port j ava.util.StringTokeni z er;10.11./**12. *13. *@author 刘长炯14. *m odi by jzj15. *16. */17.public class Si m pleHttpServer i m ple m ents Runnable {18.19. ServerSocket serverSocket;//服务器Socket20.21. public static int PORT =80;//标准HTTP端口22.23. public String encoding = "GB K";24.25. public Si m pleHttpServer() {26. try {27. serverSocket = ne w ServerSocket(PORT);28. } catch (E x ception e) {29. e.printStackTrace();30. Syste m.e x it(1);31. }ne w Thread(this).start();Syste m.out.println("HTTP服务器正在运行,端口:" + PORT);32. }33.34. public void run() {35. w hile (true) {36. try {37. Socket client = serverSocket.accept();//客户机(这里是 IE 等浏览器)已经连接到当前服务器38. i f (client != null) {39. Syste m.out.println("连接到服务器的用户:" + client);40. try {41. // 第一阶段: 打开输入流42. InputStrea m is = client.getInputStrea m();43.44. Syste m.out.println("客户端发送的请求信息: >>>>>>>>>>>>>>>>>>>>>>>>>");45. // 读取第一行, 请求地址46. String line = readLine(is, 0);47. //打印请求行48. Syste m.out.print(line);49. // < Method > < URL > < HTTP Version > <\r\n> 取的是URL部分50. String resource = line.substring(line.inde x O f('/'), line51. .lastInde x O f('/') - 5);52. //获得请求的资源的地址53. resource = URLDecoder.decode(resource, encoding);//反编码 URL 地址54. String m ethod = ne w StringTokeni z er(line).ne x tEle m ent()55. .toString();// 获取请求方法, GET 或者 POST56. int contentLength =0;//如果为POST方法,则会有消息体长度57.58. // 读取所有浏览器发送过来的请求参数头部信息59. do {60. line = readLine(is, 0);61. //如果有Content-Length消息头时取出62. i f (line.startsWith("Content-Length")) {63. contentLength = Integer.parseInt(line.split(":")[1]64. .tri m());65. }66. //打印请求部信息67. Syste m.out.print(line);68. //如果遇到了一个单独的回车换行,则表示请求头结束69. } w hile (!line.e q uals("\r\n"));70. //如果是POST请求,则有请求体71. i f ("POST".e q ualsIgnoreCase(m ethod)) {72. //注,这里只是简单的处理表单提交的参数,而对于上传文件这里是不能这样处理的,73. //因为上传的文件时消息体不只是一行,会有多行消息体74. Syste m.out.print(readLine(is, contentLength));75. Syste m.out.println();76. }77.78. Syste m.out.println("客户端发送的请求信息结束 <<<<<<<<<<<<<<<<<<<<<<<<<<");79. Syste m.out.println("用户请求的资源是:" + resource);80. Syste m.out.println("请求的类型是: " +m ethod);81. Syste m.out.println();82.83. //如果是下载文件84. i f (resource.startsWith("/do w nload")) {85. f ileDo w nload("test.t x t", client);86. closeSocket(client);87. continue;88. }89.90. // GI F 图片就读取一个真实的图片数据并返回给客户端91. i f (resource.endsWith(".gi f")) {92. i m gDo w nload("test.gi f", client);93. closeSocket(client);94. continue;95. }96.97. // 请求 JPG 格式就报错 40498. i f (resource.endsWith(".j pg")) {99. PrintWriter out = ne w PrintWriter(client.getOutputStrea m(),100. true);101. out.println("HTTP/1.0 404 N ot f ound");//返回应答消息,并结束应答102. out.println();// 根据 HTTP 协议, 空行将结束头信息103. out.close();104. closeSocket(client);105. continue;106. } else {107. // 用 w riter 对客户端 socket 输出一段 HTML 代码108. PrintWriter out = ne w PrintWriter(client.getOut putStrea m(),109. true);110. out.println("HTTP/1.0 200 O K");//返回应答消息,并结束应答111. out.println("Content-Type:te x t/ht m l;charset="+ encoding);112. out.println();// 根据 HTTP 协议, 空行将结束头信息113.114. out.println("<h1> Hello Http Server</h1>"); 115. out.println("你好, 这是一个 Java HTTP 服务器 de m o 应用.<br>");116. out.println("您请求的路径是: " + resource + "<br >");117. out.println("你请求的页面含有图片:<i m g src='tes t.gi f'><br>"118.+ "<a hre f='test.gi f'>手动点击打开test.gi f 图片文件.</a>");119. out.println("<br>服务器不支持j pg格式图片,所以显示XX:"120.+ "<i m g src='test.j pg'><br><a hre f='test.j pg'>"121.+ "手动点击打开test.j pg,会跳转另一页面,并且服务返回为404错误</a><br>");122. out123. .println("<f or m m ethod=post action='/pat h?q ryPar m=POST URL查询参数' > POST 表单 "124.+ "<input na m e=userna m e value='用户'> "125.+ "<input na m e=sub m it type=sub m i t value=sub m it></f or m>");126. out127. .println("<f or m m ethod=get action='/path ?q ryPar m=GET URL查询参数' > GET 表单 "128.+ "<input na m e=userna m e value='用户'> "129.+ "<input na m e=sub m it type=sub m i t value=sub m it></f or m>");130.131. out132. .println("<f or m m ethod=post action='/pat h?q ryPar m=POST URL查询参数'"133.+ " enctype='m ultipart/f or m-data' >"134.+ "文件上传 <input type='f ile' na m e=f ile1 ><br>"135.+ " &nbs p; "136.+ "<input type='f ile' na m e=f ile2 ><b r>"137.+ " &nbs p; "138.+ "<input na m e=userna m e value='用户'> "139.+ "<input na m e=sub m it type=sub m i t value=sub m it></f or m>");140. out.println("<a hre f='/do w nload'>点击此处模拟文件下载</a>");141.142. out.close();143.144. closeSocket(client);145. }146. } catch (E x ception e) {147. Syste m.out.println("HTTP服务器错误:" + e.getLoca li z edMessage());148. }149. }150. //Syste m.out.println(client+"连接到HTTP服务器");//如果加入这一句,服务器响应速度会很慢151. } catch (E x ception e) {152. Syste m.out.println("HTTP服务器错误:" + e.getLocali z ed Message());153. }154. }155. }156.157. /*158.* 这里我们自己模拟读取一行,因为如果使用API中的Bu ff eredReader时,它是读取到一个回车换行后159.*才返回,否则如果没有读取,则一直阻塞,这就导致如果为POST 请求时,表单中的元素会以消息体传送,160.* 这时,消息体最末按标准是没有回车换行的,如果此时还使用Bu ff eredReader来读时,则POST提交161.* 时会阻塞。