今天复习了一下socket的知识,看了一些网上博客的代码,参考了一下自己也照着写了一个服务端与客户端的互撩demo
首先写一个客户端
package j2se;
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 Server {
public static void main(String[] args) {
try {
//初始化服务器端socket
ServerSocket serverSocket=new ServerSocket(8888);
//等待客户端连接
System.out.println("等待连接");
Socket socket=serverSocket.accept();
System.out.println("服务器有连接进来了");
//通过socket获取字符流
BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//获取输入的字符流
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
//获取客户端的输入流
BufferedReader bufferedReader2=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String msg;
while(true){
msg=bufferedReader2.readLine();
if("bye".equals(msg)||msg==null){
System.out.println("服务器端消息:\n"+msg);
System.out.println("聊天结束!");
break;
}
System.out.println("来自客户端的消息:\n"+msg);
System.out.println("服务器端输入:");
String str = bufferedReader.readLine();
bufferedWriter.write(str);
bufferedWriter.write("\n");
bufferedWriter.flush();
}
socket.close();
bufferedReader.close();
bufferedReader2.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
然后是客户端,在字符流后面加上一个\n,作为标识告诉服务端客户端已经输入完了
package j2se;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
try {
Socket socket=new Socket("127.0.0.1", 8888);
//通过socket获取字符流
BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//获取输入的字符流
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
//获取服务器端的字符流
BufferedReader bufferedReader2=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
while(true){
System.out.println("客户端输入:");
String str = bufferedReader.readLine();
bufferedWriter.write(str);
bufferedWriter.write("\n");
bufferedWriter.flush();
if("bye".equals(str)||str==null){
System.out.println("聊天结束");
break;
}
String msg=bufferedReader2.readLine();
System.out.println("来自服务器端消息:\n"+msg);
}
socket.close();
bufferedReader.close();
bufferedReader2.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
分别运行起来
server
client
用“bye”作为聊天结束的标识,程序结束
但是这里可以看到,我们现在的程序是单线程的,同一时间,要么收消息,要么发消息,不能同时进行。
下面就做一点修改,用多线程实现同时收发。对上面代码做出修改,新增SendThread.java和ReceviceThread.java并且它们都继承了Thread
SendThread.java
package socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
public class SendThread extends Thread {
private Socket socket;
public SendThread(Socket socket){
this.socket = socket;
}
public void run(){
try {
//通过socket获取字符流
BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//获取输入的字符流
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
while(true){
System.out.println("请输入:");
String str = bufferedReader.readLine();
bufferedWriter.write(str);
bufferedWriter.write("\n");
bufferedWriter.flush();
if("bye".equals(str)||str==null){
System.out.println("聊天结束");
break;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ReceviceThread.java
package socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReceviceThread extends Thread {
private Socket socket;
public ReceviceThread(Socket socket) {
this.socket = socket;
}
public void run(){
try {
//获取客户端的输入流
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String msg;
while(true){
msg=bufferedReader.readLine();
if("bye".equals(msg)||msg==null){
System.out.println("收到消息:\n"+msg);
System.out.println("聊天结束!");
break;
}
System.out.println("收到消息:\n"+msg);
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
重新修改Server.java
package socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
ServerSocket serverSocket=new ServerSocket(8888);
//等待客户端连接
System.out.println("等待连接");
Socket socket=serverSocket.accept();
System.out.println("服务器有连接进来了");
//启动发送消息线程
new SendThread(socket).start();
//启动接受消息线程
new ReceviceThread(socket).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Client.java
package socket;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Socket socket=new Socket("127.0.0.1",8888);
// 启动发送消息线程
new SendThread(socket).start();
// 启动接受消息线程
new ReceviceThread(socket).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在控制台看到,我们可以一直向服务端发送消息,服务端也能一直受到消息或者发送消息