需求如下:
客户端 :向服务器端发送信息,并接收服务器端的反馈信息.
服务器端 :接收客户端发来的信息并反馈信息给客户端.
实现如下 :
import java.io.*;
import java.net.*;
import java.util.*;public class Tcp{ public void yReceiverSend(int port)
{
ServerSocket serveSocket = null;
Socket clientSocket = null;
BufferedInputStream input = null;
InputStream inputStream = null;
OutputStream outputStream = null;
byte[] buffer = new byte[1024]; //平台生成的XML串
ByteArrayOutputStream streamXML = new ByteArrayOutputStream(); //请求数据存放对象 try{
serveSocket = new ServerSocket(port); //在指定端口建立一个连接
System.out.println("开始监听:");
while (true){
clientSocket = serveSocket.accept(); //收到一个信息,得到一个clientSocket
clientSocket.setSoTimeout(5000);
inputStream = clientSocket.getInputStream(); //数据缓冲区
int count = 0; //每个缓冲区的实际数据长度
try {
input = new BufferedInputStream(inputStream);
while ((count = input.read(buffer)) != -1){
streamXML.write(buffer, 0, count);
}
}catch (Exception e){
e.printStackTrace();
} System.out.println("收到客户端发来的如下信息: " + streamXML.toString());
streamXML.reset();
outputStream = clientSocket.getOutputStream();
buffer = "我是服务器,你的请求已经收到!".getBytes(); //反馈信息
outputStream.write(buffer);
outputStream.flush();
outputStream.close();
inputStream.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
public void send(String host,int port){
InputStream inputStream = null;
byte[] buffer = new byte[1024];
try{
Socket socket = new Socket("192.168.61.146",20000);
socket.setSoTimeout(0);
OutputStream outputStream = socket.getOutputStream();
BufferedInputStream input = null;
ByteArrayOutputStream streamXML = new ByteArrayOutputStream();
buffer = "abcdefghijklmnopqrstuvwxyz".getBytes(); //要发给服务器端的信息
outputStream.write(buffer);
outputStream.flush();
System.out.println("发送数据完毕!!!");//---------------------------------------------------------------------------
//接收服务器端的反馈
buffer = "".getBytes();
inputStream = socket.getInputStream(); int count = 0;
try {
input = new BufferedInputStream(inputStream);
while ((count = input.read(buffer)) != -1){//到这里就有问题了
streamXML.write(buffer, 0, count);
}
}catch (Exception e){
e.printStackTrace();
}finally{
if (input != null){
try {
input.close();
}catch (Exception f){
f.printStackTrace();
}
}
}
//----------------------------------------------------------------------------
System.out.println("收到服务器的如下反馈:" + streamXML.toString());
inputStream.close();
outputStream.close();
socket.close();
streamXML.reset();
}catch (Exception e){
e.printStackTrace();
}
}
}
问题如下:
如果客户端只发送信息而不接收服务器的反馈时,程序执行正常.
如果接收反馈时,收不到反馈,在我标注的地方就定住了.哪位高手能解决我的这个需求哦~我一定会好好感谢.
大家也可以给出建议,最好能把解决的代码给我.谢谢了 .
分不够再加100.
客户端 :向服务器端发送信息,并接收服务器端的反馈信息.
服务器端 :接收客户端发来的信息并反馈信息给客户端.
实现如下 :
import java.io.*;
import java.net.*;
import java.util.*;public class Tcp{ public void yReceiverSend(int port)
{
ServerSocket serveSocket = null;
Socket clientSocket = null;
BufferedInputStream input = null;
InputStream inputStream = null;
OutputStream outputStream = null;
byte[] buffer = new byte[1024]; //平台生成的XML串
ByteArrayOutputStream streamXML = new ByteArrayOutputStream(); //请求数据存放对象 try{
serveSocket = new ServerSocket(port); //在指定端口建立一个连接
System.out.println("开始监听:");
while (true){
clientSocket = serveSocket.accept(); //收到一个信息,得到一个clientSocket
clientSocket.setSoTimeout(5000);
inputStream = clientSocket.getInputStream(); //数据缓冲区
int count = 0; //每个缓冲区的实际数据长度
try {
input = new BufferedInputStream(inputStream);
while ((count = input.read(buffer)) != -1){
streamXML.write(buffer, 0, count);
}
}catch (Exception e){
e.printStackTrace();
} System.out.println("收到客户端发来的如下信息: " + streamXML.toString());
streamXML.reset();
outputStream = clientSocket.getOutputStream();
buffer = "我是服务器,你的请求已经收到!".getBytes(); //反馈信息
outputStream.write(buffer);
outputStream.flush();
outputStream.close();
inputStream.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
public void send(String host,int port){
InputStream inputStream = null;
byte[] buffer = new byte[1024];
try{
Socket socket = new Socket("192.168.61.146",20000);
socket.setSoTimeout(0);
OutputStream outputStream = socket.getOutputStream();
BufferedInputStream input = null;
ByteArrayOutputStream streamXML = new ByteArrayOutputStream();
buffer = "abcdefghijklmnopqrstuvwxyz".getBytes(); //要发给服务器端的信息
outputStream.write(buffer);
outputStream.flush();
System.out.println("发送数据完毕!!!");//---------------------------------------------------------------------------
//接收服务器端的反馈
buffer = "".getBytes();
inputStream = socket.getInputStream(); int count = 0;
try {
input = new BufferedInputStream(inputStream);
while ((count = input.read(buffer)) != -1){//到这里就有问题了
streamXML.write(buffer, 0, count);
}
}catch (Exception e){
e.printStackTrace();
}finally{
if (input != null){
try {
input.close();
}catch (Exception f){
f.printStackTrace();
}
}
}
//----------------------------------------------------------------------------
System.out.println("收到服务器的如下反馈:" + streamXML.toString());
inputStream.close();
outputStream.close();
socket.close();
streamXML.reset();
}catch (Exception e){
e.printStackTrace();
}
}
}
问题如下:
如果客户端只发送信息而不接收服务器的反馈时,程序执行正常.
如果接收反馈时,收不到反馈,在我标注的地方就定住了.哪位高手能解决我的这个需求哦~我一定会好好感谢.
大家也可以给出建议,最好能把解决的代码给我.谢谢了 .
分不够再加100.
BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter( socket.getOutputStream())); 全改成:DataOutputStream bWriter = new DataOutputStream(
socket.getOutputStream());
读写方法用readUTF();writeUTF();原因是因为频繁使用readLine()方法,因此必须在发消息的时候加上"\r\n",否则该方法会阻塞.不行就用上面的方法
to liufei8463(武汉小兵)
你的理解错误的
BufferedInputStream实际上是对InputStream实现缓冲封装,这样可以提高效率。所以不但不可以不用,反而要多用才好。DataInputStream只不过对InputStream简单封装一下,解决了一些基本数据转换的问题,没有什么太大的变化,尤其对byte数组读写。
用BufferedReader也不可取,这个是对字符流做读写的,不是对字节流。lz的读写虽然是针对String的,但用BufferedReader来代替在其他情况下就会出问题。readUTF对于其他语言的tcp接口不支持,少用为好
lz的问题是buffer = "".getBytes();
你把buffer设置成了一个byte数组,但长度是0。为什么这样做呢?直接buffer=new byte[4096]不就可以了吗。费了好大的力气才找出来,汗
http://community.csdn.net/Expert/topic/5165/5165981.xml?temp=.1623194
liufei8463(武汉小兵)
你写的代码不是我程序里的呀!
这个是什么阿?
你的代码真的还需要好好琢磨一下。比较乱。这个只能是让你知道Stream的用法,典型得TCP通信得例子还是别的好我3楼的说法你要看看,这样来实现缓冲是不可以的,必须要buffer=new byte[4096]的形式。至于liufei8463(武汉小兵) 的说法我不苟同。他贴的那个帖子我也有点异议,不过已经结的就不说了。
拟定问题出在while ( (count = input.read(buffer)) != -1) 这句话
InputStream读取数据,当read的数据量大于0的时候返回读取字节数,当遇到结尾的时候返回-1。这个说法不确切。
实际上只有InputStream的public int read()方法才是完全这样的。它会一个字节一个字节的读取,当读到流末尾的时候会返回-1。而public int read(byte b[], int off, int len)并不是这样。这个方法只有当读取的第一个字节就是流末尾时才会返回-1。
举个例子:
socket传输数据包,长度1000个字节
如果我们buffer=new byte[1024];
第一次input.read(buffer)返回1000,但第二次read的时候并不是返回-1;而是在这里等待.因为上次读取时流已经到末尾了.
一般在做流输出的时候都要加上自己的包头,用来描述包的长度.
如在发送buffer之前先发送一个int数据或者一个固定长度的string,接收也一样,解析后得到总长度,然后按照这个长度去接收剩余的数据.
这个确实是个问题,我原来不是buffer = "".getBytes();这么写的.就是new byte[1024]现在就是客户端建立一个socket 用它来发送信息. 服务器端已经能收到了.
(我用//---------------标记的部分注释掉,程序运行正常.)但是把//--------这部分加到程序里就不行了!
但是服务器端返回的信息客户端不能收到.
谢谢大家了 呵呵!尤其谢谢!fool_leave(请及时结贴)
InputStream is;
OutputStream os;
//大量数据传输最好用Buffered流
BufferedInputStream bis=new BufferedInputStream(is);
BufferedOutputStream bos=new BufferedOutputStream(os);
假设每次读取1个String,都发送0x01返回给对方,表示成功
发送数据部分://准备字符串发送
String data="aaaaaaaaaaaaa";
byte buf[]=data.getBytes();
//准备数据头
byte headbuf[]=new byte[4];
String head=String.valueOf(buf.length);
System.arraycopy(head.getBytes(),0,headbuf,0,4);
//这里我采用String作为头只是为了方便和其他语言的tcp链接,不然需要高低位转换
//你也可以自己去设计头
//net 工作
bos.write(headbuf);
bos.write(buf);
bos.flush();
int res=bis.read();
if(res!=0x01){
System.out.println("err");
}
接收部分:
//一样准备头缓存
byte headbuf[]=new byte[4];
//接收头
bis.read(headbuf);
String head=new String(headbuf).trim();
//得到数据长度
int len=Integer.parseInt(head);
//创建数据buffer
byte buf[]=new byte[len];
//读取数据
bis.read(buf);
//回执
bos.write(0x01);
bos.flush();我没有调试,应该有拼写错误
重要的是思路
对于头部分每个人的习惯不同,你可以自己设计头数据
这里没有捕捉错误,也没有考虑异常,你自己写代码时别忘了怎么样,满意否?汗,现在在csdn上积分真不易呀