客户端代码:package com.test.client;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class TestClient {
public static void main(String[] args) {
OutputStream out = null;
InputStream in = null;
try {
Socket client = new Socket("192.168.2.103",6000);
out = client.getOutputStream();
in = client.getInputStream(); DataOutputStream dataout = new DataOutputStream(out);
String ss ="wwwwwwwwwwwwwwwwwwwwwwwwww";
byte b[] = ss.getBytes();
int bl = b.length;
System.out.println("客户端字节大小:"+ bl);
dataout.write(b,0,bl);
dataout.flush();
DataInputStream datain = new DataInputStream(in);
String s = null;
if((s=datain.readUTF())!=null)
{
System.out.println(s);
}
dataout.close();
datain.close();
client.close();
System.out.println("client close");
// dataout.writeUTF("你好");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务端代码:
package com.test.server;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TestServer {
public static void main(String[] args) {
OutputStream out = null;
InputStream in = null;
try {
ServerSocket serverSocket = new ServerSocket(6000);
System.out.println("服务创建");
while(true)
{
System.out.println("开始监听");
System.out.println("服务对象:"+serverSocket);
Socket client = serverSocket.accept();
in=client.getInputStream();
out = client.getOutputStream(); DataInputStream datain = new DataInputStream(in);
int aaa = datain.available();
System.out.println("客户端发过来的字节数为:"+aaa);
byte b [] = new byte[aaa];
datain.read(b);
String ss= new String(b);
System.out.println("-"+ss);
DataOutputStream dataout = new DataOutputStream(out);
dataout.writeUTF("服务器收到:"+ss);
datain.close();
dataout.flush();
dataout.close();
System.out.println("-----------完成----------\n");
client.close();
System.out.println("server close");
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.exit(0);
e.printStackTrace();
} }}
为什么我的客户端 只有第一次运行的时候有效两边的 数组长度都会显示出26,服务器端打印,也会反馈给客户端
而 当我服务端不动第二次运行的客户端的时候时候 服务端就不会把客户端传过去的数据打印,而且服务端得到的数据长度为0
这里我特意使用了byte 数组传送数据
以前我使用writeUTF readUTF 不会出问题。
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class TestClient {
public static void main(String[] args) {
OutputStream out = null;
InputStream in = null;
try {
Socket client = new Socket("192.168.2.103",6000);
out = client.getOutputStream();
in = client.getInputStream(); DataOutputStream dataout = new DataOutputStream(out);
String ss ="wwwwwwwwwwwwwwwwwwwwwwwwww";
byte b[] = ss.getBytes();
int bl = b.length;
System.out.println("客户端字节大小:"+ bl);
dataout.write(b,0,bl);
dataout.flush();
DataInputStream datain = new DataInputStream(in);
String s = null;
if((s=datain.readUTF())!=null)
{
System.out.println(s);
}
dataout.close();
datain.close();
client.close();
System.out.println("client close");
// dataout.writeUTF("你好");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务端代码:
package com.test.server;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TestServer {
public static void main(String[] args) {
OutputStream out = null;
InputStream in = null;
try {
ServerSocket serverSocket = new ServerSocket(6000);
System.out.println("服务创建");
while(true)
{
System.out.println("开始监听");
System.out.println("服务对象:"+serverSocket);
Socket client = serverSocket.accept();
in=client.getInputStream();
out = client.getOutputStream(); DataInputStream datain = new DataInputStream(in);
int aaa = datain.available();
System.out.println("客户端发过来的字节数为:"+aaa);
byte b [] = new byte[aaa];
datain.read(b);
String ss= new String(b);
System.out.println("-"+ss);
DataOutputStream dataout = new DataOutputStream(out);
dataout.writeUTF("服务器收到:"+ss);
datain.close();
dataout.flush();
dataout.close();
System.out.println("-----------完成----------\n");
client.close();
System.out.println("server close");
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.exit(0);
e.printStackTrace();
} }}
为什么我的客户端 只有第一次运行的时候有效两边的 数组长度都会显示出26,服务器端打印,也会反馈给客户端
而 当我服务端不动第二次运行的客户端的时候时候 服务端就不会把客户端传过去的数据打印,而且服务端得到的数据长度为0
这里我特意使用了byte 数组传送数据
以前我使用writeUTF readUTF 不会出问题。
可能因为server段的while循环(接收第一个client) 还没结束(你用的是阻塞的接受方法)数据没接收完 就等待(阻塞)
所以 还不能接收第二个client 所以输出的数据为空
建议在server 每accept一个client 就输出下提示信息
要想做个好的server-client 肯定得用线程的
package com.test.server;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.TimeUnit;public class TestServer {
public static void main(String[] args) {
OutputStream out = null;
InputStream in = null;
try {
ServerSocket serverSocket = new ServerSocket(6000);
System.out.println("服务创建");
while(true)
{
System.out.println("开始监听");
System.out.println("服务对象:"+serverSocket);
Socket client = serverSocket.accept();
in=client.getInputStream();
out = client.getOutputStream(); DataInputStream datain = new DataInputStream(in);
//int aaa = datain.available();
int aaa = 1024;
System.out.println("客户端发过来的字节数为:"+aaa);
byte b [] = new byte[aaa];
int size = 0;
String ss = null;
if((size = datain.read(b))!= -1){
ss = new String(b, 0, size);
System.out.println("-"+ss);
}
DataOutputStream dataout = new DataOutputStream(out);
System.out.println(System.currentTimeMillis() % 1000);
dataout.writeUTF("服务器收到:"+ss);
datain.close();
dataout.flush();
dataout.close();
System.out.println("-----------完成----------\n");
client.close();
System.out.println("server close");
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.exit(0);
e.printStackTrace();
}
}}
下面这行是检查socket输入流中数据长度的。
int aaa = datain.available();
这里会有两种情况。和执行顺序有关。
1. 如果客户端先把数据写入socket,不会出问题。
2. 如果客户端线程在服务器线程之后,尚未向socket写入数据。aaa = 0;当出现第二章情况的时候。
b是一个长度为0的数组。
datain.read(b); 什么都没读出来。服务器继续往下执行,一直到关闭流,关闭socket。这时候回过头来执行客户端,因为服务器把流和socket都关闭啦,所以客户端就出差了。
处理方法是,当有新客户端连接服务器,为这个socket开启一个新线程。
在线程内有点像这样: int aaa = 1024;
byte b [] = new byte[aaa];
int size = 0;
String ss = null;
while(true){
// 线程会在这里阻塞,直到读取到客户端发过来的数据
// 终止循环的一个方法,客户端直接关闭socket和流(也包括非正常断线),datain.read(b)会抛出异常。
size = datain.read(b);
// 一下是对读取到数据执行具体业务逻辑。
// 服务器和客户端之间应该有完整的协议。何时中断连接,服务器如何回应客户端请求等等
ss = new String(b, 0, size);
System.out.println("-"+ss);
// 这个例子,收到"EXIT"终止循环,可以看做服务器和客户端协议的一部分。这样下面可以由服务器主动断开连接。
if("EXIT".equals(ss)){
break;
}
}
上面只是一个简单例子。实际做起来当然不见得就这样。