计算机网络实验课的时候,要写个用到套接字的小程序,调了半天,对java的流操作有点感悟。最后吐槽一下鄙学院的计算机网络实验课,果断置软件本科生智商于不顾,
试验本身没有什么建设性,实验指导书更是事无巨细,婆婆妈妈,第一步要干这个噢,第二步要干这个哦,与其这样还不如提供一个自动生实验报告及提交脚本,点一下自动交作业。
言归正传,java的输入输出都是建立在流上,
输出流,也就是outputStream,最基本的方法就是write(int b) 输出一字节的数据(0-255)如果int的值大于255,则会丢掉超出的3个字节的数据,将int转换为byte。java其他输出流的很多方法都应该是基于这个虚拟方法的。当然,一次次的读是很耗时的,所以java提供了一种实现了缓存技术的流bufferedWriter
bufferedReader 这两个他们会把已经写的数据和将要读的数据,存入缓冲区,以后再一次性的读或者写,在网络传输的时候,使用缓冲区技术会使速度大幅加快。需要注意写的时候,流会等待缓冲区满的时候才把数据传过去,可以使用flush()方法传输缓冲区数据,缓冲区大小可以设置,不过一般默认即可,使用close()关闭流后,缓冲区数据消失。
buffered的实现与原理在这里http://hi.baidu.com/google_sunzn/blog/item/61d64c5047f60d7d84352427.html
输入流,最基本的方法是这个read(),他会返回一个(0-255)之间的数,-1表示流的结尾,read()方法会阻塞程序的进行,直到该方法的得到一个字节,所以读的速度会非常慢,最好放在一个新的线程里。因为返回类型是int 所以使用它的时候可以这样。
byte[] input=new byte[10];for(int i=0;i
int b=in.read(); if(b==-1) break; input[i]=(byte)b;}
不过java里面的byte是有符号byte(-128-127)与read()返回的无符号byte,稍稍不同,可以这样转换一下,吧有符号装换成无符号。
int i=b>=0?b:256+b;
为了提高效率java提供了read(byte[] data)他会返回实际读取的字节数,来应对只读取带一部分字节的情况,如果想确定读取完成,可以这样
int bytesRead=0;int byteToRead=1024;
byte[] input=new byte[byteToRead];
while(bytesRead+=in.read(input,bytesRead,byteToRead-bytesRead);}
最后说一下printwriter这个流也是支持缓存的,不过不支持手动调用方法,flush(),也不会抛出异常,有点神奇。
文档在这里http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html 好像得翻墙才能看。
最后最后说一下,bufferReader的readLine()方法会挂起等待换行符 而 bufferWriter的write()方法是不会包含换行符的,除非手动输入"\n",可以调用nextLine(),
他会根据系统不同插入换行符。
顺便把代码贴上来,简单实现了一个可以互相通信的socket
服务端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class service {
private PrintWriter pw;
private BufferedReader br;
private ServerSocket ss;
private Socket s;
public static void main(String[] args) {
new service().start(); //在static方法中调用非static方法
}
public void start() {
// TODO Auto-generated method stub
try {
ss = new ServerSocket(2223);
while (true) {
s = ss.accept();
pw = new PrintWriter(s.getOutputStream(), true);
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
String msg = "";
try {
// while(true) {
while (true) {
msg = br.readLine();
System.out.println("client:" + msg);
if (msg.equals("NAK"))
pw.println("NAK");
else if (msg.equals("TL"))
pw.println("TL");
else
pw.println("ACK");
}
// }
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while (true) {
Scanner s = new Scanner(System.in);
String msg = s.next();
pw.println(msg);
}
}
}).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class client {
private PrintWriter pw;
private BufferedReader br;
private BufferedWriter bw;
private Socket s;
/**
* @param args
*/
public static void main(String[] args) {
new client().start();
}
public void start() {
// TODO Auto-generated method stub
try {
s = new Socket("127.0.0.1", 2223);
pw = new PrintWriter(s.getOutputStream(), true);
bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
String msg = "";
try {
while (true) {
msg = br.readLine();
System.out.println("server:" + msg);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while (true) {
//Scanner s = new Scanner(System.in);
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
//String msg = s.next();
String msg="";
try{
msg = bf.readLine();
pw.println(msg);
//bw.write(msg);
//bw.newLine();
//bw.flush();
}catch(Exception e){
e.printStackTrace();
}
}
}
}).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}