<pre name="code" class="java">public class Client {
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Socket s=new Socket("127.0.0.1",3000);
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String line=br.readLine();
System.out.println(line);;
br.close();
s.close();
}
}
public class Server {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
ServerSocket server=new ServerSocket(3000);
while(true)
{
//获取连接的客户端
Socket s=server.accept();
PrintStream ps=new PrintStream(s.getOutputStream());//向Socket输入数据
ps.println("您好,收到服务器发出的新年祝福");
ps.close();
s.close();
}
}
}
加入多线程
前面的代码只是实现了两个实体的简单通信,实际中的客户端可能需要和服务器端保持较长时间的通信,即服务器端需要不断的读取客户端数据,并向客户端写入数据,客户端也需要不断的读取服务器端的数据,并向服务器端写入数据。
一个命令行界面的C/S聊天室应用,服务器端应该包含多个线程,每个Socket对应一个线程,该线程负责读取Socket对应输入流的数据(从客户端发送过来的数据),并将输入的数据向每个Socket输出流发送一个,因此需要在服务器端使用List来保存所有的Socket
public class MyServer {
//用来保存所有的Socket对象
public static ArrayList<Socket> list= new ArrayList<Socket>();
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
ServerSocket server = new ServerSocket(3000);
while(true)
{
Socket socket = server.accept();
list.add(socket);
//为每一个Socket启动线程
new Thread(new ServerThread(socket)).run();
}
}
}
public class ServerThread implements Runnable {
Socket s=null;
BufferedReader br=null;
public ServerThread(Socket socket) throws IOException
{
this. s = socket;
//初始化Socket对应的输入流
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
}
@Override
public void run() {
// TODO Auto-generated method stub
try
{
String content = null;
while((content = readFromClient())!=null)
{
for(Socket s:MyServer.list)
{
PrintStream ps = new PrintStream(s.getOutputStream());
ps.println(content);
}
}
}catch(IOException e)
{
e.printStackTrace();
}
}
//定义读取客户端数据的方法
private String readFromClient() {
// TODO Auto-generated method stub
try
{
return br.readLine();
}catch(IOException e)
{
MyServer.list.remove(s);
}
return null;
}
}
上面的服务器端线程类不断的读取客户端数据,程序使用readFromClient()方法来读取客户端数据,如果读取数据过程中捕获到异常,则表明该Socket对应的客户端Socket出现了问题,将从list集合中删除。
每个客户端包含两个线程,一个负责读取用户的键盘输入,并将用户输入的数据写入Socket对应的输出流中,一个负责读取Socket对应输入流中的数据(从服务器端发送过来的数据),并将这些数据打印输出。
public class MyClient {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Socket s = new Socket("127.0.0.1",3000);
new Thread(new ClientThread(s)).start();
PrintStream ps = new PrintStream(s.getOutputStream());
String line = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while((line=br.readLine()) != null)
{
ps.println(line);
}
}
}
public class ClientThread implements Runnable {
private Socket s=null;
BufferedReader br=null;
public ClientThread(Socket socket) throws IOException
{
this.s=socket;
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
}
public void run() {
// TODO Auto-generated method stub
try
{
String content =null;
while((content =br.readLine())!=null)
{
System.out.println(content);
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}