今天覆習了一下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();
}
}
}
在控制檯看到,我們可以一直向服務端發送消息,服務端也能一直受到消息或者發送消息