Socket 接收本地短连接并转发为长连接 多线程

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.servlet.http.HttpServlet;

/**
* @author 某家:
* @version 创建时间:2015年8月18日 上午10:35:04
* 类说明
*/

public class TestConnect extends HttpServlet {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private static final ThreadLocal<Socket> threadConnect = new ThreadLocal<Socket>(); 

    private static final String HOST = "106.3.44.235";

    private static final int PORT = 8888;

    //发送至通道方
    private static Socket client;

    //接收本地消息
    private static ServerSocket serverSocket;

    //本地客户端
    private static Socket localClient;

    private static OutputStream outStr = null;

    private static InputStream inStr = null;

    private static Thread tKeep = new Thread(new KeepThread());
    private static Thread tRecv = new Thread(new RecvThread());
    private static Thread tSend = new Thread(new SendThread());
    private static Thread tClient = new Thread(new ClientThread());

    public static void connect() throws UnknownHostException, IOException  {
        if(client == null){
            client = new Socket(HOST, PORT);
            threadConnect.set(client);
            tKeep.start();
            System.out.println("========链接开始!========");
        }
        outStr = client.getOutputStream();
        inStr = client.getInputStream();
    }

    public static void disconnect() {
        try {
            outStr.close();
            inStr.close();
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static String sendMsg(String str){
        System.out.println("======发送数据:"+str+"====");
        try {
            outStr.write(str.getBytes());
            while (true) {
                byte[] b = new byte[1024];
                int r = inStr.read(b);
                if(r>-1){
                    System.out.println(new String(b).trim());
                    return new String(b).trim();
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }
    /**
     * 向外发送——保持心跳包
     * @author 某家
     *
     */
    private static class KeepThread implements Runnable {
        public void run() {
            try {
                System.out.println("=====================开始发送心跳包==============");
                while (true) {
                    try {
                        Thread.sleep(30000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    //System.out.println("发送心跳数据包");
                    outStr.write("send heart beat data package !".getBytes());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
    /**
     * 向外接收——接收并转发给本地短连接
     * @author 某家
     *
     */
    private static class RecvThread implements Runnable {

        public void run() {
            try {
                System.out.println("RecvThread 开始接收上游渠道信息信息!");
                while (!Thread.currentThread().isInterrupted()) {
                    PushbackInputStream serverinput = new PushbackInputStream(inStr);
                    byte[] inbyte = new byte[serverinput.available()];
                    int len = serverinput.read(inbyte);
                    if(len > 0){
                        System.out.println("RecvThread len:" + len + "; " + new String(inbyte, 0, len));
                        localClient.getOutputStream().write(inbyte);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 向外发送——接收本地短连接并发送给上游渠道
     * @author 某家
     *
     */
    private static class SendThread implements Runnable {
        public void run() {
            try {
                System.out.println("SendThread 开始接收本地端链接信息!");
                while(!Thread.currentThread().isInterrupted()){
                    PushbackInputStream serverinput = new PushbackInputStream(localClient.getInputStream());
                    byte[] inbyte = new byte[serverinput.available()];
                    int len = serverinput.read(inbyte);
                    if(len > 0){
                        System.out.println("SendThread len:" + len + "; " + new String(inbyte, 0, len));
                        outStr.write(inbyte);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    private static class ClientThread implements Runnable {
        private static boolean flag = false;
        public void run() {
            try {
                while (true) {
                    // 一旦有堵塞, 则表示服务器与客户端获得了连接
                    localClient = serverSocket.accept();
                    System.out.println("localClient 已获取到:" +localClient.getLocalPort());
                    if(!flag){
                        tRecv.start();
                        tSend.start();
                        flag = true;
                    }
                }
            } catch (IOException e ) {
                e.printStackTrace();
            }

        }
    }

    public void init(){
        System.out.println("=============================init function ================");
        try {
            TestConnect.connect();
            TestConnect.service();
            //tRecv.start();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void destroy(){
        System.out.println("=============================destroy function ================");
        TestConnect.disconnect();
    }

    public static void service(){
        try {
            System.out.println("=============================service function ================");
            serverSocket = new ServerSocket(9999);
            tClient.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
} 
时间: 2024-11-05 12:25:26

Socket 接收本地短连接并转发为长连接 多线程的相关文章

http中长连接和websocket的长连接的区别(转)

转自https://www.cnblogs.com/Catherine001/p/8359153.html 一.什么是http协议 HTTP是一个应用层协议,无状态的,端口号为80.主要的版本有1.0/1.1/2.0. HTTP/1.* 一次请求-响应,建立一个连接,用完关闭: HTTP/1.1 串行化单线程处理,可以同时在同一个tcp链接上发送多个请求,但是只有响应是有顺序的,只有上一个请求完成后,下一个才能响应.一旦有任务处理超时等,后续任务只能被阻塞(线头阻塞): HTTP/2 并行执行.

http中长连接和websocket的长连接的区别

HTTP是一个应用层协议,无状态的,端口号为80.主要的版本有1.0/1.1/2.0. HTTP/1.* 一次请求-响应,建立一个连接,用完关闭: HTTP/1.1 串行化单线程处理,可以同时在同一个tcp链接上发送多个请求,但是只有响应是有顺序的,只有上一个请求完成后,下一个才能响应.一旦有任务处理超时等,后续任务只能被阻塞(线头阻塞): HTTP/2 并行执行.某任务耗时严重,不会影响到任务正常执行 二.什么是websocket Websocket是html5提出的一个协议规范,是为解决客户

[Go] 测试go连接imap的tcp长连接

连接上imap服务后,什么都不操作,我测试大约5分钟会被服务端断掉,测试代码如下 imapClient, _ := client.Dial("imap.sina.net:143") for { time.Sleep(time.Second * 1) } 为了保持住这条连接,每隔10秒列取一下邮件夹列表,这样就可以一直保持住连接了.开三个窗口,一个窗口不停的netstat查看tcp连接情况,一个窗口运行代码,一个窗口打开tcpdump监听端口查看数据请求 while true;do cl

(转载) 长连接与短连接的区别(tcp socket http概念原理一样)

原文地址:http://blog.sina.com.cn/s/blog_6d39b5be0101k6v4.html 一.长连接与短连接:长连接:client方与server方先建立连接,连接建立后不断开,然后再进行报文发送和接收.这种方式下由于通讯连接一直存在.此种方式常用于P2P通信.短连接:Client方与server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接.此方式常用于一点对多点通讯. 二.长连接与短连接的操作过程:短连接的操作步骤是:建立连接--数据传输--关闭连接

TCP/IP,http,socket,长连接,短连接——小结(转)

概要: 之前对这几个概念有点糊涂,查阅了些资料,稍微概括下他们的区别吧.如有错误,请拍~~~ 先看图: TCP/IP是什么? TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层.    在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议.    在传输层中有TCP协议与UDP协议.    在应用层有FTP.HTTP.TELNET.SMTP.DNS等协议. Socket是什么呢? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,一组接口,把复杂的T

Java实现Socket长连接和短连接

1概念 Socket:socket实际上是对TCP/IP进行的封装,我们可以使用socket套接字通过socket来传输.首先我们需要明白的一个概念就是通道,简单地说通道就是两个对端可以随时传输数据的信道.我么常说的所谓建立socket连接,也就是建立了客户端与服务器端的通道. 长短连接:显而易见,长连接也就是这个socket连接一直保持连接,也就是通道一直保持通畅,两个对端可以随时发送和接收数据:短连接就是我们发送一次或有限的几次,socket通道就被关闭了.首先,我们必须明白的是socket

java如何实现Socket的长连接和短连接

讨论Socket必讨论长连接和短连接 一.长连接和短连接的概念 1.长连接与短连接的概念:前者是整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接:后者是每次请求,都新建一个Socket,处理完一个请求就直接关闭掉Socket.所以,其实区分长短连接就是:整个客户和服务端的通讯过程是利用一个Socket还是多个Socket进行的. 可能你会想:这还不简单,长连接不就是不关Socket嘛,短连接不就是每次都关Socket每次都new Socket嘛.然而事实其实并没有

Socket的长连接和短连接

讨论Socket必讨论长连接和短连接 一.长连接和短连接的概念 1.长连接与短连接的概念:前者是整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接:后者是每次请求,都新建一个Socket,处理完一个请求就直接关闭掉Socket.所以,其实区分长短连接就是:整个客户和服务端的通讯过程是利用一个Socket还是多个Socket进行的. 可能你会想:这还不简单,长连接不就是不关Socket嘛,短连接不就是每次都关Socket每次都new Socket嘛.然而事实其实并没有

socket短连接、长连接

通常短连接是这样:连接->传输数据->关闭连接那什么是长连接?一般长连接相对短连接而言的,长连接在传输结束后不关闭连接,而不断的发送包保持连接等待处理下一个数据包. 一般长连接用于少数client-end to server-end的频繁的通信,例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,而且频繁的socket创建也是对资源的浪费.而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的