关于tcp套接字得到输入输出流的问题 本帖最后由 dnfpyz2012 于 2011-11-06 19:56:31 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 因为你在发送文件的时候,直接把bw给关闭了,这样导致socket关闭,然后在接收的时候就会出现问题,而且你的server和client都不严谨,server程序很明显在并发的时候会出错,线程不能这样些,顺便附上我简单修改过的,表达能力不行,希望你能理解Serverpackage server;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class Server { private int port; Server(int port) { this.port = port; } public void StartServer() { try { ServerSocket server = new ServerSocket(port); while (true) { try{ new Thread(new ServerProcess(server.accept())).start(); }catch(Exception ex){ ex.printStackTrace(); } } } catch (IOException e) { System.out.println("ServerSocket创建失败!检查端口"+port+"是否被占用"); e.printStackTrace(); } }}class ServerProcess implements Runnable{ private static final String SEND_PATH = "D:/dos命令参数.txt"; //发送文件路径 private static final String RECV_PATH = "D:/hello.java"; //接收文件路径 private InputStream in; private OutputStream out; ServerProcess(Socket socket) { try { in = socket.getInputStream(); out = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("socket 错误!"); } } ////////////////接收//////////////// private void receive() { FileOutputStream fileOut = null; try { File file_receive = new File(RECV_PATH); fileOut = new FileOutputStream(file_receive); pipe(fileOut,in); } catch (IOException e) { e.printStackTrace(); }finally{ if(null != fileOut){ try { fileOut.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("文件接收已完成!"); } private void pipe(OutputStream out,InputStream in) throws IOException { byte[] buf = new byte[512]; int len = 0; while((len = in.read(buf)) != -1) { out.write(buf,0,len); } }/////////////////////发送///////////////////////// private void send(){ FileInputStream fileIn = null; try { File file_send = new File(SEND_PATH); fileIn = new FileInputStream(file_send); pipe(out,fileIn); System.out.println("文件发送已完成!"); } catch (IOException e) { e.printStackTrace(); }finally{ if(null != fileIn) { try { fileIn.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Override public void run() { try{ send(); receive(); }finally{ try { in.close(); } catch (IOException e) { e.printStackTrace(); }finally{ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }}Server启动代码 new Server(6666).StartServer();Clientpackage client;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;public class Client { private static final String SEND_PATH = "D:/dos命令参数1.txt"; private static final String RECV_PATH = "D:/hello1.java"; private InputStream in; private OutputStream out; Client(String host, int port) { try { Socket socket = new Socket(host, port); in = socket.getInputStream(); out = socket.getOutputStream(); } catch (UnknownHostException e) { System.out.println("无法找到主机:" + host); e.printStackTrace(); throw new RuntimeException(e); } catch (IOException e) { System.out.println("可能是端口错误 :" + port); e.printStackTrace(); throw new RuntimeException(e); } } // //////////////发送///////////////////////// private void send() { InputStream fileIn = null; try { fileIn = new FileInputStream(SEND_PATH); pipe(out, fileIn); System.out.println("文件发送完成"); } catch (IOException e) { e.printStackTrace(); }finally{ if(null != fileIn) { try { fileIn.close(); } catch (IOException e) { e.printStackTrace(); } } } } // ///////////////////接收///////////////////// private void receive() { OutputStream fileOut = null; try { fileOut = new FileOutputStream(RECV_PATH); pipe(fileOut,in); System.out.println("文件接收已完成!"); } catch (IOException e) { e.printStackTrace(); }finally{ if(null != fileOut){ try { fileOut.close(); } catch (IOException e) { e.printStackTrace(); } } } } private void pipe(OutputStream out, InputStream in) throws IOException { byte[] buf = new byte[512]; int len = 0; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } } public void run() { try{ send(); receive(); }finally{ try{ in.close(); }catch(IOException e){ e.printStackTrace(); }finally{ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }}Client启动代码new Client("127.0.0.1",6666).run();最后还有一个小小的建议,发送和接受文件不要弄成同一个,比较容易出错 你的代码中只能读入1个文件, 传送,然后写入一个文件。并不支持多个文件的读入,和多个文件的写入。你只要在Server中结束一个文件时,重新new出所有流(包括一个新文件)在客户端中,写完第一个文件时,重新建立所有流(包括一个新输入文件),所有的socket不要动,还用原来的,也不要释放就可以。 别管怎么说 先谢谢你们两位了~~第一次写tcp的东西,自己确实不怎么会~~东拼西凑了这么个东西,我自己再改改,谢谢两位的回答 我的代码给你参考:import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import javax.swing.JLabel;import javax.swing.JTextArea;public class GetMessage extends Thread{ private int i; String v; JLabel label=null; private JTextArea text; Date d=new Date(); SimpleDateFormat matter=new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒"); public GetMessage(int i,JTextArea text) { this.i=i; this.text=text; } public void run(){ try { ServerSocket so = new ServerSocket(i); Socket s = so.accept(); while(true){ InputStreamReader i = new InputStreamReader(s.getInputStream()); BufferedReader b = new BufferedReader(i); v= b.readLine(); text.append(String.valueOf(matter.format(d))+"\n"); text.append("对方说"+v+"\n"); } } catch (IOException e) { System.out.println(e.getMessage()); //label.setText("对方已经下线"); text.append("对方下线了"); } }}import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.Socket;import java.net.UnknownHostException;import javax.swing.JLabel;import javax.swing.JTextArea;import javax.swing.JTextField;public class SendMessage extends Thread { private String ip; private int i; Socket s = null; JLabel label=null; JTextField text; JTextArea text1; public SendMessage(String ip,int i,JTextArea text1) { // TODO Auto-generated constructor stub this.ip=ip; this.i=i; this.text1=text1; } public void run(){ while(true){ try { s = new Socket(ip,i); text1.setText("连接成功"+"\n"); break; } catch (Exception e) { try { Thread.sleep(1000); } catch (InterruptedException e1) { System.out.println("出错了。"); } } } } public void send(String message) { try { PrintStream p = new PrintStream(s.getOutputStream()); p.println(message); } catch (Exception e1) { System.out.println("异常"+e1.getMessage()); } } } 恩 你这个聊天软件也不错哈 头回发提问帖,谢谢各位好心人的回复这会仔细读了下二楼的代码~~~哥们谦虚了,很严谨的程序,受教了。我还想知道的是为什么我关闭bw的时候会关闭 socket而二楼的代码却不会?领悟能力有限,哪位好心人给解答下~ 额,上一个问题二了~~~~二楼的代码没有关闭过 in和 out,只在最后文件传输完毕后关闭了这两个流。如果想在in和out上再包上其它的高层流该,比如说BufferedReader,BufferedWriter啥的,怎么处理?也不关闭么?会不会存在什么问题? 对于socket编成1、client连上后,如果是同步短连接的话,数据传输完后需要关闭is和os,同时关闭socket。2、如果是长连接的话,就什么都不要关。3、你用BufferedReader,BufferedWriter最终都是调用了socket相关的inputstream和outputStream,BufferedReader,BufferedWriter只是对这两个流进行包装,最终数据传输完成,还是要参照1、2 你在调用 BufferedReader,BufferedWriter的close方法,方法内部什么自己调用被 包装类的close方法,所以你只需要显示的调用 BufferedReader,BufferedWriter的close方法即可 数据类型小问题---请各位帮忙指点? public void launchFrame() 是干什么用的 在API中找不到它? 关于POI的setPageStart无效问题,急,在线等 请指教下java信息国际化怎么实现 页面 刷新/缓存 问题 怎样实现模糊查询!! Double tt= new Double() 10个大洋,解释一条语句!!马上给分!!! 如何注册jbuilder6 personal,马上给分 向各位高手求教 请问这个乱码肿木办嘞 TitleBorder现在不能用吗???
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {
private int port;
Server(int port) {
this.port = port;
}
public void StartServer() {
try {
ServerSocket server = new ServerSocket(port);
while (true) {
try{
new Thread(new ServerProcess(server.accept())).start();
}catch(Exception ex){
ex.printStackTrace();
}
}
} catch (IOException e) {
System.out.println("ServerSocket创建失败!检查端口"+port+"是否被占用");
e.printStackTrace();
} }
}class ServerProcess implements Runnable{
private static final String SEND_PATH = "D:/dos命令参数.txt"; //发送文件路径
private static final String RECV_PATH = "D:/hello.java"; //接收文件路径
private InputStream in;
private OutputStream out;
ServerProcess(Socket socket) {
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("socket 错误!");
}
}
////////////////接收////////////////
private void receive() {
FileOutputStream fileOut = null;
try {
File file_receive = new File(RECV_PATH);
fileOut = new FileOutputStream(file_receive);
pipe(fileOut,in);
} catch (IOException e) {
e.printStackTrace();
}finally{
if(null != fileOut){
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("文件接收已完成!");
}
private void pipe(OutputStream out,InputStream in) throws IOException {
byte[] buf = new byte[512];
int len = 0;
while((len = in.read(buf)) != -1) {
out.write(buf,0,len);
}
}
/////////////////////发送/////////////////////////
private void send(){
FileInputStream fileIn = null;
try {
File file_send = new File(SEND_PATH);
fileIn = new FileInputStream(file_send);
pipe(out,fileIn);
System.out.println("文件发送已完成!");
} catch (IOException e) {
e.printStackTrace();
}finally{
if(null != fileIn) {
try {
fileIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public void run() {
try{
send();
receive();
}finally{
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}Server启动代码 new Server(6666).StartServer();Clientpackage client;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Client {
private static final String SEND_PATH = "D:/dos命令参数1.txt";
private static final String RECV_PATH = "D:/hello1.java"; private InputStream in;
private OutputStream out; Client(String host, int port) {
try {
Socket socket = new Socket(host, port);
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (UnknownHostException e) {
System.out.println("无法找到主机:" + host);
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
System.out.println("可能是端口错误 :" + port);
e.printStackTrace();
throw new RuntimeException(e);
}
} // //////////////发送/////////////////////////
private void send() {
InputStream fileIn = null;
try {
fileIn = new FileInputStream(SEND_PATH);
pipe(out, fileIn);
System.out.println("文件发送完成");
} catch (IOException e) {
e.printStackTrace();
}finally{
if(null != fileIn) {
try {
fileIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} // ///////////////////接收/////////////////////
private void receive() {
OutputStream fileOut = null;
try {
fileOut = new FileOutputStream(RECV_PATH);
pipe(fileOut,in);
System.out.println("文件接收已完成!");
} catch (IOException e) {
e.printStackTrace();
}finally{
if(null != fileOut){
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} private void pipe(OutputStream out, InputStream in) throws IOException {
byte[] buf = new byte[512];
int len = 0;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
public void run() {
try{
send();
receive();
}finally{
try{
in.close();
}catch(IOException e){
e.printStackTrace();
}finally{
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}}Client启动代码
new Client("127.0.0.1",6666).run();最后还有一个小小的建议,发送和接受文件不要弄成同一个,比较容易出错
你只要在Server中结束一个文件时,重新new出所有流(包括一个新文件)
在客户端中,写完第一个文件时,重新建立所有流(包括一个新输入文件),所有的socket不要动,还用原来的,也不要释放就可以。
第一次写tcp的东西,自己确实不怎么会~~东拼西凑了这么个东西,我自己再改改,谢谢两位的回答
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;import javax.swing.JLabel;
import javax.swing.JTextArea;
public class GetMessage extends Thread{
private int i;
String v;
JLabel label=null;
private JTextArea text;
Date d=new Date();
SimpleDateFormat matter=new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
public GetMessage(int i,JTextArea text) { this.i=i;
this.text=text;
}
public void run(){
try {
ServerSocket so = new ServerSocket(i);
Socket s = so.accept();
while(true){
InputStreamReader i = new InputStreamReader(s.getInputStream());
BufferedReader b = new BufferedReader(i);
v= b.readLine();
text.append(String.valueOf(matter.format(d))+"\n");
text.append("对方说"+v+"\n");
}
} catch (IOException e) {
System.out.println(e.getMessage());
//label.setText("对方已经下线");
text.append("对方下线了");
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class SendMessage extends Thread {
private String ip;
private int i;
Socket s = null;
JLabel label=null;
JTextField text;
JTextArea text1;
public SendMessage(String ip,int i,JTextArea text1) {
// TODO Auto-generated constructor stub
this.ip=ip;
this.i=i;
this.text1=text1;
}
public void run(){
while(true){
try {
s = new Socket(ip,i);
text1.setText("连接成功"+"\n");
break;
} catch (Exception e) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
System.out.println("出错了。");
}
}
}
}
public void send(String message)
{
try {
PrintStream p = new PrintStream(s.getOutputStream()); p.println(message);
} catch (Exception e1) {
System.out.println("异常"+e1.getMessage());
}
}
}
这会仔细读了下二楼的代码~~~哥们谦虚了,很严谨的程序,受教了。
我还想知道的是为什么我关闭bw的时候会关闭 socket而二楼的代码却不会?领悟能力有限,哪位好心人给解答下~
1、client连上后,如果是同步短连接的话,数据传输完后需要关闭is和os,同时关闭socket。
2、如果是长连接的话,就什么都不要关。
3、你用BufferedReader,BufferedWriter最终都是调用了socket相关的inputstream和outputStream,BufferedReader,BufferedWriter只是对这两个流进行包装,最终数据传输完成,还是要参照1、2