java如何实现socket连接方法封装

目录
  • Java实现socket连接技巧
  • Java Socket的封装
    • 1 客户端Socket API要点
    • 2 服务端Socket API要点
    • 常见问题
  • Java使用socket实现一个多线程web服务器的方法
    • 除了服务器类,还包括请求类和响应类
    • 服务器处理类
    • 请求类
    • 响应类

Java实现socket连接技巧

Socket通信几乎无时不在,当然能够搜集到的信息也大量存在, 为了避免重复的劳作, 抽取了关于客户端和服务端的Socket, 并将其应用到适合JVM(LInux/Windows)或者DVM(Android)平台。

这个封装好的API具有以下优势:

1.满足具有Socket客户端需求的基本应用。

2.满足具有Socket服务端的基本应用。具备并发能力, 能满足可设定个数客户端连接。

本文的目的就是为了对Socket做一个封装, 方便客户端和服务端能直接使用Socket.封装好的API可以从下面获取

Java Socket的封装

其中src/中的是API源码; usage/目录是使用例程

1 客户端Socket API要点

1)客户端和指定的服务端相连, 因此客户端需要指明服务端对应的IP地址和端口号

2)需要设置超时返回

3)需要设置循环等待, 因为基本的Socket通信都是一来一回, 这种来回是通过阻塞来完成的。

4)每个客户端连入服务端的时候, 都具备本身的ID, 类似于HTTP的Session, 这点容易被忽视。在多客户端连接中, 可以重点关注。本文提供的代码也有所提及, 但没有深入, 这点留给读者进一步发掘。

代码参照/usage目录下的客户端测试代码, 注意, 先启动服务端,或者你拿着NetAssis 来测试也不错.

2 服务端Socket API要点

1)服务端一般是被多个客户端连接的, 并且这些连接要求服务端做相似的处理, 因此这里就将这些相似处理, 抽象成一个SingleTask.java 接口, 具体的业务只需要实现这样的接口, 就可以并行的处理这些Task.

2)不能无限制的让客户端连入Server, 因此需要设置上限值

3)启动线程池, 每个线程针对一个具体的客户端连接

4)注意接收阻塞位置, 需要设置死循环, 读不到数据将死守着等待(但别耽误其它线程处理事情)

5)注意服务端要在死循环中侦听, 这样保证不错过任何来自客户端的请求。

代码参照:/usage目录下的Server端测试代码。

代码中注释很多,因此这里就不详细述说。

常见问题

1、客户端Client的时候, 如果存在网络问题, 为了避免网络问题,造成客户端长时间等待, 此时要设置一个TimeOut

clientSocket = new Socket();
//这个TimeOut是连接等待时间
clientSocket.connect(tcpAddress, timeOut);

2、当客户端已经连接, 每次收到一个数据, 客户端将启动处理, 假如服务器长久不发数据, 此时客户端会阻塞等待, 为了避免这个时候的等待, 可以设置一个超时

clientSocket.setSoTimeout(timeOut);

Java使用socket实现一个多线程web服务器的方法

除了服务器类,还包括请求类和响应类

请求类:获取客户的HTTP请求,分析客户所需要的文件响应类:获得用户请求后将用户需要的文件读出,添加上HTTP应答头。发送给客户端。

服务器处理类

package com.lp.app.webserver;
import java.io.*;
import java.net.*;
//使用Socket创建一个WEB服务器,本程序是多线程系统以提高反应速度。
class WebServer
{
public static String WEBROOT = "";//默认目录
 public static String defaultPage = "index.htm";//默认文件
 public static void main (String [] args) throws IOException
 {
 System.out.println ("服务器启动...\n");
  //使用8080端口提供服务
 ServerSocket server = new ServerSocket (8080);
 while (true)
 {
  //阻塞,直到有客户连接
  Socket sk = server.accept ();
  System.out.println ("Accepting Connection...\n");
  //启动服务线程
  new WebThread (sk).start ();
 }
 }
}
//使用线程,为多个客户端服务
class WebThread extends Thread
{
 private Socket sk;
 WebThread (Socket sk)
 {
  this.sk = sk;
 }
 //线程体
 public void run ()
 {
  InputStream in = null;
  OutputStream out = null;
  try{
  in = sk.getInputStream();
  out = sk.getOutputStream();
  //接收来自客户端的请求。
  Request rq = new Request(in);
  //解析客户请求
  String sURL = rq.parse();
  System.out.println("sURL="+sURL);
  if(sURL.equals("/"))
    sURL = WebServer.defaultPage;
  Response rp = new Response(out);
  rp.Send(sURL);
   }
  catch (IOException e)
  {
  System.out.println (e.toString ());
  }
  finally
  {
  System.out.println ("关闭连接...\n");
  //最后释放资源
  try{
   if (in != null)
   in.close ();
   if (out != null)
   out.close ();
   if (sk != null)
   sk.close ();
  }
  catch (IOException e)
  {
  }
  }
 }
}

请求类

package com.lp.app.webserver;
import java.io.*;
import java.net.*;
//获取客户的HTTP请求,分析客户所需要的文件
public class Request{
 InputStream in = null;
 //获得输入流。这是客户的请求数据。
 public Request(InputStream input){
 this.in = input;
 }
 //解析客户的请求
 public String parse() {
 //从Socket读取一组数据
 StringBuffer requestStr = new StringBuffer(2048);
 int i;
 byte[] buffer = new byte[2048];
 try {
 i = in.read(buffer);
 }
 catch (IOException e) {
 e.printStackTrace();
 i = -1;
 }
 for (int j=0; j<i; j++) {
 requestStr.append((char) buffer[j]);
 }
 System.out.print(requestStr.toString());
 return getUri(requestStr.toString());
 }
 //获取URI信息字符
 private String getUri(String requestString) {
 int index1, index2;
 index1 = requestString.indexOf(' ');
 if (index1 != -1) {
 index2 = requestString.indexOf(' ', index1 + 1);
 if (index2 > index1)
  return requestString.substring(index1 + 1, index2);
 }
 return null;
 }
}

响应类

package com.lp.app.webserver;
import java.io.*;
import java.net.*;
//获得用户请求后将用户需要的文件读出,添加上HTTP应答头。发送给客户端。
public class Response{
 OutputStream out = null;
 //发送请求的文件 public void Send(String ref) throws IOException {
 byte[] bytes = new byte[2048];
 FileInputStream fis = null;
 try {
 //构造文件
 File file = new File(WebServer.WEBROOT, ref);
 if (file.exists()) {
  //构造输入文件流
  fis = new FileInputStream(file);
  int ch = fis.read(bytes, 0, 2048);
  //读取文件
  String sBody = new String(bytes,0);
  //构造输出信息
  String sendMessage = "HTTP/1.1 200 OK\r\n" +
  "Content-Type: text/html\r\n" +
  "Content-Length: "+ch+"\r\n" +
  "\r\n" +sBody;
  //输出文件
  out.write(sendMessage.getBytes());
 }else {
  // 找不到文件
  String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
  "Content-Type: text/html\r\n" +
  "Content-Length: 23\r\n" +
  "\r\n" +
  "<h1>File Not Found</h1>";
  out.write(errorMessage.getBytes());
 }
 }
 catch (Exception e) {
 // 如不能实例化File对象,抛出异常。
 System.out.println(e.toString() );
 }
 finally {
 if (fis != null)
  fis.close();
 }
 }
 //获取输出流
 public Response(OutputStream output) {
 this.out = output;
}
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • java 实现websocket的两种方式实例详解

    一.介绍 1.两种方式,一种使用tomcat的websocket实现,一种使用spring的websocket 2.tomcat的方式需要tomcat 7.x,JEE7的支持. 3.spring与websocket整合需要spring 4.x,并且使用了socketjs,对不支持websocket的浏览器可以模拟websocket使用 二.方式一:tomcat 使用这种方式无需别的任何配置,只需服务端一个处理类, 服务器端代码 package com.Socket; import java.io

  • Java实现简单的socket通信教程

    今天学习了一下java如何实现socket通信,感觉难点反而是在io上,因为java对socket封装已经很完善了. 今天代码花了整个晚上调试,主要原因是io的flush问题和命令行下如何运行具有package的类,不过最后问题基本都解决了,把代码贴出来供大家参考 server public class TcpServer { public static void main(String[] args) throws Exception { ServerSocket server = new S

  • 详解Java Socket通信封装MIna框架

    核心类 IoService :Mina中将服务端和客户端都看成是服务,这里提供统一接口IoService,这个接口的作用就是用来处理套接字机制.也正是IoService来监听消息返回消息这些步骤,可以说IoService就是我们Mina中核心 IoProcessor:这个接口在另一个线程上,负责检查是否有数据在通道上读写,也就是说它也拥有自己的Selector,这是与我们使用JAVA NIO 编码时的一个不同之处,通常在JAVA NIO 编码中,我们都是使用一个Selector,也就是不区分Io

  • java实现socket客户端连接服务端

    本例只做简单功能演示,代码并不严谨,只是说明客户端如何实现连接服务端简单代码. 代码在集成Eclipse工具下测试编译运行环境如下图所示: 客户端echoClient.java代码: package com.zhengzz.echo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java

  • java如何实现socket连接方法封装

    目录 Java实现socket连接技巧 Java Socket的封装 1 客户端Socket API要点 2 服务端Socket API要点 常见问题 Java使用socket实现一个多线程web服务器的方法 除了服务器类,还包括请求类和响应类 服务器处理类 请求类 响应类 Java实现socket连接技巧 Socket通信几乎无时不在,当然能够搜集到的信息也大量存在, 为了避免重复的劳作, 抽取了关于客户端和服务端的Socket, 并将其应用到适合JVM(LInux/Windows)或者DVM

  • Java使用代理进行网络连接方法示例

    需求是这样的: 一.界面上要有这样几种代理类型可以选. 1.HTTP代理 2.Socks代理 3.不使用代理(直连) 4.使用浏览器设置(浏览器也是HTTP.Socks.直连三种). 可参考QQ登录设置里的代理能,其实跟qq的代理功能是一样的. 二.测试使用所填写的代理配置信息是否可连接 三.记录用户上次选择的代理配置,默认使用用户上次使用的代理配置进行网络连接. 程序运行环境是WindowsXP.Windows7.Windows8系统. 使用的技术为Java7,Swing,CXF. 难点: 1

  • 如何解决线程太多导致java socket连接池出现的问题

    这篇文章主要介绍了如何解决线程太多导致socket连接池出现的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 线程太多导致socket连接池爆满,进程启动不了 问题: 某部机上跟其它机器的连接有问题,ping可以通,telnet端口不通,可以其它机器可以连接到该机器上的进程. java应用启动不起来,产生以下错误. java.net.SocketException: No buffer space available (maximum co

  • Android编程实现基于局域网udp广播自动建立socket连接的方法

    本文实例讲述了Android编程实现基于局域网udp广播自动建立socket连接的方法.分享给大家供大家参考,具体如下: android开发中经常会用到socket通讯.由于项目需要,最近研究了一下这方面的知识. 需求是想通过wifi实现android移动设备和android平台的电视之间的文件传输与控制. 毫无疑问这中间一定需要用到socket来进行通信.今天就两台设备的握手连接方式分享一下吧,该方法只是本人个人想法的实现,仅供参考,如有雷同,不胜荣幸. 要想使用socket进行通讯,就必须知

  • python使用socket连接远程服务器的方法

    本文实例讲述了python使用socket连接远程服务器的方法.分享给大家供大家参考.具体如下: import socket print "Creating socket...", s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print "done." print "Looking up port number...", port = socket.getservbyname('htt

  • Java编程利用socket多线程访问服务器文件代码示例

    这篇文章将向大家展示Java编程利用socket多线程访问服务器文件代码示例,如果您想先了解Java多线程socket编程的基础知识,可以看下这篇文章:Java多线程编程实现socket通信示例代码. 接下来进入正文,我们看看利用socket多线程访问服务器代码: ServerMain.java package com.ysk.webServer; import java.io.File; import java.io.IOException; import java.net.ServerSoc

  • Java实现心跳机制的方法

    一.心跳机制简介 在分布式系统中,分布在不同主机上的节点需要检测其他节点的状态,如服务器节点需要检测从节点是否失效.为了检测对方节点的有效性,每隔固定时间就发送一个固定信息给对方,对方回复一个固定信息,如果长时间没有收到对方的回复,则断开与对方的连接. 发包方既可以是服务端,也可以是客户端,这要看具体实现.因为是每隔固定时间发送一次,类似心跳,所以发送的固定信息称为心跳包.心跳包一般为比较小的包,可根据具体实现.心跳包主要应用于长连接的保持与短线链接. 一般而言,应该客户端主动向服务器发送心跳包

  • socket连接关闭问题分析

    socket编程过程中往往会遇到这样那样的问题,出现了这些问题,有的是由于并发访问量太大造成的,有些却是由于代码中编程不慎造成的.比如说,最常见的错误就是程序中报打开的文件数过多这个错误.socket建立连接的时候是三次握手,这个大家都很清楚,但是socket关闭连接的时候,需要进行四次挥手,但很多人对于这四次挥手的具体流程不清楚,吃了很多亏. CLOSE_WAIT分析 socket是一种全双工的通信方式,建立完socket连接后,连接的任何一方都可以发起关闭操作.这里不妨假设连接的关闭是客户端

  • Java 实现简单Socket 通信的示例

    目录 1. 传输层协议 2. TCP 示例 2.1 示例效果 2.2 服务端程序代码 3. UDP 示例 3.1 服务端程序代码 3.2 客户端程序代码 Java socket 封装了传输层的实现细节,开发人员可以基于 socket 实现应用层.本文介绍了 Java socket 简单用法. 1. 传输层协议 传输层包含了两种协议,分别是 TCP (Transmission Control Protocol,传输控制协议) 和 UDP (User Datagram Protocol,用户数据报协

  • java实现TCP socket和UDP socket的实例

    目录 概述 传输层概述 TCP套接字编程 大致过程 详细过程 UDP套接字编程 补充 概述 我们在网络编程时,通常是让我们本地的应用程序和远程的应用程序进行通信,也就是分布式的进程之间的通信,比如我写的程序A和小明的程序B进行通信,我的程序运行时在本机就是一个进程,是有pid号的,小明的也是.那这两个程序是怎么通信的呢? 这就要理解网络分层的概念了,网络层实现的是主机到主机之间的通信,网络层的实现是ip协议,通过各自的ip地址就能实现远程数据传输,而网络层只是保证了主机A的数据能够到达主机B,并

随机推荐