Java网络编程中怎样用管道流

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java网络编程中怎样用管道流相关的知识,希望对你有一定的参考价值。

Java网络编程中利用TCP协议怎样将服务器与客户端设计成多线程并用管道流通信相互通信

一起学习,管道流满搞的,用着比socket的stream麻烦
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.channels.*;
import java.nio.*;
import java.util.*;
import java.nio.charset.*;
public class TCP extends Thread
private SocketChannel channel;
private ServerSocket serverSocket;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer readBuffer;
private ByteBuffer sendBuffer;
private Boolean isAccept=false;
private boolean isConnect=false;
private Thread accept;
private Thread connect;
/** Creates a new instance of TCP */
public TCP(int port,String addr)
try
readBuffer=ByteBuffer.allocate(1024);
serverSocketChannel=ServerSocketChannel.open();
serverSocket=serverSocketChannel.socket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(port));
channel=SocketChannel.open();
channel.connect(new InetSocketAddress(InetAddress.getByName(addr),port));
accept=new Thread()
public void run()
Selector selector;
try
selector=Selector.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
isAccept=false;
selectors(selector);
catch (ClosedChannelException ex)
ex.printStackTrace();
catch (IOException ex)
ex.printStackTrace();


;
connect=new Thread()
public void run()
try
Selector selector;
selector=Selector.open();
channel.configureBlocking(false);
channel.register(selector,SelectionKey.OP_WRITE|SelectionKey.OP_READ);
isConnect=false;
selectors(selector);
catch (Exception ex)
ex.printStackTrace();


;
catch (IOException ex)
ex.printStackTrace();
System.out.println("d1");
catch(Exception ex)
System.out.println("d2");


private void service()
if(isConnect)
connect.start();

if(isAccept)
accept.start();


private void selectors(Selector selector)
try
while (selector.select()>0)
Set readyKeys=selector.selectedKeys();
Iterator<SelectionKey> it=readyKeys.iterator();
while(it.hasNext())
SelectionKey key=null;
key=it.next();
it.remove();
if(key.isAcceptable())
//System.out.println("isAcceptable");
ServerSocketChannel ssc=(ServerSocketChannel)key.channel();
SocketChannel socketChannel=ssc.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE);

if(key.isReadable())
synchronized(readBuffer)
// System.out.println("isReadable");
ByteBuffer buffer=ByteBuffer.allocate(1024);
SocketChannel socketChannel=(SocketChannel)key.channel();
socketChannel.read(buffer);
readBuffer=buffer;


if(key.isWritable())
synchronized(sendBuffer)
// System.out.println("isWritable");
SocketChannel channel=(SocketChannel)key.channel();
if(sendBuffer!=null)
channel.write(sendBuffer);




try
sleep(1);
catch (InterruptedException ex)
ex.printStackTrace();


catch (ClosedChannelException ex)
ex.printStackTrace();
catch (IOException ex)
ex.printStackTrace();



public void send(ByteBuffer buff)
this.sendBuffer=buff;

public ByteBuffer get()
return readBuffer;

public void accpet()
isAccept=true;

public void connect()
isConnect=true;

public void run()
while (true)
service();


参考技术A   管道流可以实现两个线程之间,二进制数据的传输。
  管道流就像一条管道,一端输入数据,别一端则输出数据。通常要分别用两个不同的线程来控制它们。
  使用方法如下:
  [html] view plaincopy
  import java.io.IOException;
  import java.io.PipedInputStream;
  import java.io.PipedOutputStream;
  
  public class PipedInputStreamTest
  
  public static void main(String[] args)
  //管道输出流
  PipedOutputStream out = new PipedOutputStream();
  //管道输入流
  PipedInputStream in = null;
  try
  //连接两个管道流。或者调用connect(Piped..);方法也可以
  in = new PipedInputStream(out);
  Thread read = new Thread(new Read(in));
  Thread write = new Thread(new Write(out));
  //启动线程
  read.start();
  write.start();
   catch (IOException e)
  e.printStackTrace();
  
  
  
  
  class Write implements Runnable
  PipedOutputStream pos = null;
  
  public Write(PipedOutputStream pos)
  this.pos = pos;
  
  
  public void run()
  try
  System.out.println("程序将在3秒后写入数据,请稍等。。。");
  Thread.sleep(3000);
  pos.write("wangzhihong".getBytes());
  pos.flush();
   catch (IOException e)
  e.printStackTrace();
   catch (InterruptedException e)
  e.printStackTrace();
   finally
  try
  if (pos != null)
  pos.close();
  
   catch (IOException e)
  e.printStackTrace();
  
  
  
  
  
  class Read implements Runnable
  PipedInputStream pis = null;
  
  public Read(PipedInputStream pis)
  this.pis = pis;
  
  
  public void run()
  byte[] buf = new byte[1024];
  try
  pis.read(buf);
  System.out.println(new String(buf));
   catch (IOException e)
  e.printStackTrace();
   finally
  try
  if (pis != null)
  pis.close();
  
   catch (IOException e)
  e.printStackTrace();
  
  
  
  
参考技术B Server端
------------------

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class Server

public static int PORT = 1007;
private ServerSocket server;
public Server() throws IOException
server = new ServerSocket(PORT);

public static void main(String[] args) throws Exception
System.out.println("--Server--");
Server server = new Server();
server.accept();


public void accept() throws IOException
Socket client = server.accept();//等待客户端的连接
getInfo(client.getInputStream());//启动等待消息线程
toInfo(client.getOutputStream());//启动发送消息线程


//等待客户端发送消息
public void getInfo(InputStream in) throws IOException
final Scanner sc = new Scanner(in);//获取客户端的输入流
new Thread()
@Override
public void run()
while(true)
if(sc.hasNextLine()) //如果客户端有发送消息过来
System.out.println("Client:" + sc.nextLine());//打印客户端的消息



.start();


//发送消息到客户端
public void toInfo(OutputStream out) throws IOException
final PrintWriter pw = new PrintWriter(out, true);//获取客户端的输出流,自动清空缓存的内容
final Scanner sc = new Scanner(System.in);//获取控制台的标准输入流,从控制台输入数据
new Thread()
@Override
public void run()
while(true)
pw.println(sc.nextLine());//将输入的数据发送给客户端


.start();



Client端
------------------------

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client

public static void main(String[] args) throws Exception, IOException
System.out.println("--Client--");
Client client = new Client();
client.connection("localhost", Server.PORT);


public void connection(String host, int port) throws IOException
Socket client = new Socket(host, port);
getInfo(client.getInputStream());
toInfo(client.getOutputStream());


public void getInfo(InputStream in) throws IOException
final Scanner sc = new Scanner(in);
new Thread()
@Override
public void run()
while(true)
if(sc.hasNextLine())
System.out.println("Server:" + sc.nextLine());



.start();


public void toInfo(OutputStream out) throws IOException
final PrintWriter pw = new PrintWriter(out, true);
final Scanner sc = new Scanner(System.in);
new Thread()
@Override
public void run()
while(true)
pw.println(sc.nextLine());


.start();

参考技术C 一起学习,管道流满搞的,用着比socket的stream麻烦
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.channels.*;
import java.nio.*;
import java.util.*;
import java.nio.charset.*;
public class TCP extends Thread
private SocketChannel channel;
private ServerSocket serverSocket;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer readBuffer;
private ByteBuffer sendBuffer;
private Boolean isAccept=false;
private boolean isConnect=false;
private Thread accept;
private Thread connect;
/** Creates a new instance of TCP */
public TCP(int port,String addr)
try
readBuffer=ByteBuffer.allocate(1024);
serverSocketChannel=ServerSocketChannel.open();
serverSocket=serverSocketChannel.socket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(port));
channel=SocketChannel.open();
channel.connect(new InetSocketAddress(InetAddress.getByName(addr),port));
accept=new Thread()
public void run()
Selector selector;
try
selector=Selector.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
isAccept=false;
selectors(selector);
catch (ClosedChannelException ex)
ex.printStackTrace();
catch (IOException ex)
ex.printStackTrace();


;
connect=new Thread()
public void run()
try
Selector selector;
selector=Selector.open();
channel.configureBlocking(false);
channel.register(selector,SelectionKey.OP_WRITE|SelectionKey.OP_READ);
isConnect=false;
selectors(selector);
catch (Exception ex)
ex.printStackTrace();


;
catch (IOException ex)
ex.printStackTrace();
System.out.println("d1");
catch(Exception ex)
System.out.println("d2");


private void service()
if(isConnect)
connect.start();

if(isAccept)
accept.start();


private void selectors(Selector selector)
try
while (selector.select()>0)
Set readyKeys=selector.selectedKeys();
Iterator it=readyKeys.iterator();
while(it.hasNext())
SelectionKey key=null;
key=it.next();
it.remove();
if(key.isAcceptable())
//System.out.println("isAcceptable");
ServerSocketChannel ssc=(ServerSocketChannel)key.channel();
SocketChannel socketChannel=ssc.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE);

if(key.isReadable())
synchronized(readBuffer)
// System.out.println("isReadable");
ByteBuffer buffer=ByteBuffer.allocate(1024);
SocketChannel socketChannel=(SocketChannel)key.channel();
socketChannel.read(buffer);
readBuffer=buffer;


if(key.isWritable())
synchronized(sendBuffer)
// System.out.println("isWritable");
SocketChannel channel=(SocketChannel)key.channel();
if(sendBuffer!=null)
channel.write(sendBuffer);




try
sleep(1);
catch (InterruptedException ex)
ex.printStackTrace();


catch (ClosedChannelException ex)
ex.printStackTrace();
catch (IOException ex)
ex.printStackTrace();



public void send(ByteBuffer buff)
this.sendBuffer=buff;

public ByteBuffer get()
return readBuffer;

public void accpet()
isAccept=true;

public void connect()
isConnect=true;

public void run()
while (true)
service();


参考技术D 管道流就像一条条水管只是有些水管没有水而已!网路流就像外来水管裏面有水!通过编程对接将网路流连接到IO流或然後将它打印出来或做其它处理。

java中的“流”是啥?

流是个抽象的概念,是对输入输出设备的抽象,java程序中,对于数据的输入/输出操作都是以“流”的方式进行。设备可以是文件,网络,内存等。
  流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流。
  可以将流想象成一个“水流管道”,水流就在这管道中形成了,自然就出现了方向的概念。
  当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件、内存或网络等等。相反地,需要写出数据到某个数据源目的地的时候,也会开启一个输出流,这个数据源目的地也可以是文件、内存或网络等等。
  可以从不同的角度对流进行分类:
  1.
处理的数据单位不同,可分为:字符流,字节流
  2.数据流方向不同,可分为:输入流,输出流
  3.功能不同,可分为:节点流,处理流
  1.

2.
都比较好理解,对于根据功能分类的,可以这么理解:
  节点流:节点流从一个特定的数据源读写数据。即节点流是直接操作文件,网络等的流,例如fileinputstream和fileoutputstream,他们直接从文件中读取或往文件中写入字节流。
  处理流:“连接”在已存在的流(节点流或处理流)之上通过对数据的处理为程序提供更为强大的读写功能。过滤流是
使用一个已经存在的输入流或输出流连接创建的,过滤流就是对节点流进行一系列的包装。例如bufferedinputstream和
bufferedoutputstream,使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率,以及datainputstream和
dataoutputstream,使用已经存在的节点流来构造,提供了读写java中的基本数据类型的功能。他们都属于过滤流。
  来源:
http://www.cnblogs.com/shitouer/archive/2012/12/19/2823641.html
参考技术A Java中的流是个抽象的概念,当程序需要从某个数据源读入数据的时候,就会开启一个数据流,数据源可以是文件、内存或网络等等。相反地,需要写出数据到某个数据源目的地的时候,也会开启一个数据流,这个数据源目的地也可以是文件、内存或网络等等

Java中的流可以从不同的角度进行分类:
按照流的方向不同:分为输入流和输出流。
按照处理数据单位的不同:分为字节流(8位)和字符流(16位)。
按照功能不同:分为节点流和处理流。
节点流:是可以从一个特定的数据源(节点)读写数据的流(例如文件,内存)。就像是一条单一的管子接到水龙头上开始放水。
处理流:是“连接”在已经存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。就像在已经接了一条管子(节点流)的基础上,又套上几个更粗,具有特殊功能的管子(处理流)对流出的水进一步的处理。
四种基本流InputStream,OutputStream,Reader,Writer又分别有更具体的子类,分为文件流,缓冲流,数据流,转换流,Print流,Object流等,都分别有特定的功能或用来操作特定的数据
参考技术B

Java的流操作分为字节流和字符流两种。

1,字节流

就是所有的写操作都继承自一个公共超类java.io.OutputStream类。

2,字符流

就是所有的写操作都继承于一个公共超类java.io.Writer类。

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。

参考技术C IO流就相当与我们日常生活中的管道,我们通过管道来把水引到用户,通过管道把石油输送到大罐.同样,我们利用流来从硬盘的文件中读数据到你的程序中,利用流来写数据到硬盘的文件
文件流 缓冲流 数据流 转换流 Print流 Object流正是为了实现这些功能的不同的类,他们具体包含了实现这些功能的方法
但如果每次都要从硬盘读取一个字节数据或写1个字节数据到硬盘,那就对硬盘损害太大了,比如电驴就损害硬盘.
解决办法:在内存中建立一个缓冲区(buffer),读一次硬盘就把缓冲区装满,然后你就可以从缓冲区读取数据,写数据的时候,先在内存中把数据写到缓冲区,写满,然后把数据一次性地从缓冲区写到硬盘.这样对硬盘的访问次数大大减少了.
缓存要交换的数据:就是读数据的时候把数据一次性读到缓冲区和写数据的时候先把数据写到缓冲区的意思
buffer是在内存中是通过字节数组实现的

以上是关于Java网络编程中怎样用管道流的主要内容,如果未能解决你的问题,请参考以下文章

Java Stream函数式编程第三篇:管道流结果处理

java中的“流”是啥?

Java文件IO流的操作总结

Java多线程编程,怎样实现线程间数据的传递?

Java网络编程:Socket 通信

在不破坏流管道的情况下引用前面的 Java 流步骤?