在这里,先澄清一下,我这里说的是一个客户端一个服务器端通信,但是它们可以自由说话,就像聊QQ一样,但是我百度到网上大多例子很多都只能客户端说一句话,服务器说一句话,这样肯定不是我们所需要的,今天为大家带来的是可以随意说话。
像这样,大家可以很容易的就想到需要多线程来处理,两个线程,一个控制socket传过来的数据,一个处理,传过去的数据,但是在传过去的时候,由于需要键盘输入,非常容易导致线程阻塞,不能继续运行,导致只能你说一句,然后我说一句。这里我把传统的InputStreamReader和OutputStreamReader改为DataInputStreamReader和DataOutputStreamReader,这样就不会导致线程阻塞了。
大概就是这样的。
InputStream is = s1.getInputStream(); //s1是socket引用
DataInputStream dis = new DataInputStream(is); //用dataInputStream包装一下然后就不会产生线程阻塞
//实例化输出流
OutputStream os = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
下面给出代码:
客户端的代码:
import java.io.*;
import java.net.*;
public class EchoClient{
public static void main(String[] args){
new EchoClient();
}
public EchoClient() {
try{
//链接sever端
Socket s1 = new Socket("localhost",8888);
//实例化输入流
InputStream is = s1.getInputStream();
DataInputStream dis = new DataInputStream(is); //用dataInputStream包装一下然后就不会产生线程阻塞
//实例化输出流
OutputStream os = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//实例化并启动两个进程
new MyClientReader(dis).start();
new MyClientWriter(dos).start();
//捕获异常
}catch(SocketException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
//创建一个进程用来进行接收读取数据
class MyClientReader extends Thread{
private DataInputStream dis;
public MyClientReader(DataInputStream dis){
this.dis = dis;
}
@Override
public void run(){
String msg;
try{
while(true){
msg = dis.readUTF();
System.out.println("对方说:"+msg);
if(msg.equals("bye")){
System.out.println("服务器下线,程序退出");
System.exit(0);
}
}
}catch(IOException e){
System.out.println(e);
}
}
}
//创建一个进程用来写入并发送数据
class MyClientWriter extends Thread{
private DataOutputStream dos;
public MyClientWriter(DataOutputStream dos){
this.dos = dos;
}
@Override
public void run(){
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String msg;
try{
while(true){
msg = br.readLine();
dos.writeUTF(msg);
if(msg.equals("bye")){
System.out.println("客户端下线,程序退出");
System.exit(0);
}
}
}catch(IOException e){
System.out.println(e);
}
}
}
服务器端代码:
import java.io.*;
import java.net.*;
public class EchoServer{
public static void main(String[] args){
new EchoServer();
}
public EchoServer() {
try{
//设置sever端的链接
ServerSocket s = new ServerSocket(8888);
System.out.println("服务器启动");
Socket s1 = s.accept();//sever等待链接
System.out.println("客户端连接===== "
+s1.getInetAddress() + ":" +s1.getPort());
//实例化输出流
OutputStream os = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//实例化输入流
InputStream is = s1.getInputStream();
DataInputStream dis = new DataInputStream(is);
//实例化两个线程的对象并启动线程
new Thread(new MyServerReader(dis)).start();
new Thread(new MyServerWriter(dos)).start();
}
//捕获异常
catch(SocketException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
//创建一个进程用来进行接收读取数据
class MyServerReader implements Runnable{
private DataInputStream dis;
public MyServerReader (DataInputStream dis){
this.dis = dis;
}
public void run(){
String msg;
try{
while(true){
msg = dis.readUTF();
System.out.println("对方说:" + msg);
if(msg.equals("bye")){
System.out.println("客户端下线,程序退出");
System.exit(0);
}
}
}catch(IOException e){
System.out.println(e);
}
}
}
//创建一个进程用来写入并发送数据
class MyServerWriter implements Runnable{
private DataOutputStream dos;
public MyServerWriter(DataOutputStream dos){
this.dos = dos;
}
public void run(){
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String msg;
try{
while(true){
msg = br.readLine();
dos.writeUTF(msg);
if(msg.equals("bye")){
System.out.println("服务器下线,程序退出");
System.exit(0);
}
}
}catch(IOException e){
System.out.println(e);
}
}
}
有什么问题可以联系我。共同进步!