server、client一对一通信已经实现,代码要怎么改才能实现client→server→client的通信呢
package com.zeph.multiclient;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class MultiThreadServer extends Thread {
private Socket client;
public MultiThreadServer(Socket c) {
this.client = c;//创建与客户端连接的socket
}
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " start");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
//利用BufferedReader实现数据的快速接收,getInputStream()获取socket底层数据输入流,InputStreamReader()实现字节到字符串的高校读取
BufferedWriter out =new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
//利用BufferedWriter实现数据的快速写入,getOutputStream()获取socket底层数据输出流,OutputStreamWriter()实现字节到字符串的高校写入
String str = in.readLine();//此方法为阻塞状态,一直到收到回车(\r)换行(\n)才结束阻塞(接收信息完毕)
while (str != null) {
System.out.println("server receive: " + str);//将接收到的信息打印出来
out.write('3');//信息写入输出流
out.flush();//写回client需要flush
System.out.println("send ok");
str = in.readLine();//读取client返回信息,此方法为阻塞状态,一直到收到回车(\r)换行(\n)才结束阻塞(接收信息完毕)
System.out.println("server receive: " + str);
str = null;//清空数据,跳出循环
}
System.out.println(Thread.currentThread().getName() + " end");
out.close();
} catch (IOException e) {
}
}
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(1234);
System.out.println("server is start!");
while (true) {
MultiThreadServer mc = new MultiThreadServer(server.accept());
if(server.getInetAddress().getHostAddress().indexOf("0.0.0.0")<0){
System.out.println("accept connect: " + server.getInetAddress().getHostAddress());
}
mc.start();
}
}
}
------解决思路----------------------
楼主,你服务器接受两个soket,然后把一个的输入流的信息通到另一个的输出流里面去(一个输入流一个输出流配成一对,一共两对),就可以了。
楼上说的对,由于你用的是同步阻塞io,每一对流都需要一个独立的线程来倒腾数据,不然会有不发数据就收不到数据的问题。
------解决思路----------------------
阻塞IO
服务器端:两个ServerSocket,分别监视两个client,每个client多线程处理
------解决思路----------------------
package chat;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 聊天室客户端
*
* java.net.Socket
* 封装了TCP协议的Socket
* 通过它来连接服务端的ServerSocket
* 并创建输入输出流来与服务端通信。
*
* /sbin/ifconfig
*
*
* @author Administrator
*
*/
public class Client {
//用来与服务端通信的Socket
private Socket socket;
/**
* 构造方法,用来初始化客户端
* 构造方法常用来初始化对象属性等操作。
*/
public Client(){
try {
/*
* 初始化Socket时需要传入两个参数
* 1:服务端的IP地址
* 2:服务端的端口号
*
* 首先要清楚:
* 通讯是客户端计算机上的一个客户端应用程序
* 与服务端计算机(俗称服务器)上的一个服务端
* 应用程序之间的通讯。
*
* IP地址的作用是让我们通过网络可以找到服务器
* 而端口可以让我们找到运行在服务器上的服务端
* 应用程序。
*
* 创建Socket实例的过程就是与服务端连接的
* 过程, 若可以成功与服务器连接上,则会创建
* Socket实例,否则构造方法会抛出异常。
*/
System.out.println("正在尝试连接服务端...");
socket = new Socket("localhost",8088);
System.out.println("与服务端连接成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 客户端开始工作的方法
*/
public void start(){
try {
/*
* 当客户端启动后,就启动接收服务端发送过来
* 消息的线程
*/
GetServerMessageHandler handler
= new GetServerMessageHandler();
Thread t = new Thread(handler);
t.start();
/*
* 创建一个Scanner用来获取用户输入
*/
Scanner scanner = new Scanner(System.in);
/*
* OutputStream getOutputStream()
* Socket提供了该方法,用来获取输出流来向
* 服务端发送数据。
*/
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw
= new OutputStreamWriter(out,"UTF-8");
PrintWriter pw = new PrintWriter(osw,true);
while(true){
String message = scanner.nextLine();
pw.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
/**
* 由于接收服务端发送过来的消息,与我们给服务端
* 发送消息没有必然关系,所以两者应当在两个不同
* 的线程上完成,各做各的,互不干涉。
* @author Administrator
*
*/
private class GetServerMessageHandler
implements Runnable{
public void run() {
try {
/*
* 该线程的职责就是读取服务端发送过来的
* 每一条消息,并输出到控制台。
*/
InputStream in = socket.getInputStream();
InputStreamReader isr
= new InputStreamReader(in,"UTF-8");
BufferedReader br
= new BufferedReader(isr);
String message = null;
while((message=br.readLine())!=null){
System.out.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}