Case1:读写不同步TCP
服务器端
package FUXI;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Serverdemo_FX {
public static void main(String[] args) {
int port=9999;
ServerSocket svr=null;
Socket socket=null;
try {
svr=new ServerSocket(port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//等待连接
socket=svr.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//读写操作
BufferedReader read=null;
PrintWriter write=null;
try {
read=new BufferedReader(new InputStreamReader(socket.getInputStream()));
write=new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true) {
try {
System.out.println(read.readLine());
Scanner in=new Scanner(System.in);
write.println(in.nextLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
客户端
package FUXI;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Clientdemo_FY {
public static void main(String[] args) {
//创建客户端,建立连接
String host="127.0.0.1";
int port=9999;
Socket client=null;
try {
client=new Socket(host,port);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//读写数据
BufferedReader read=null;
PrintWriter write=null;
Scanner in=new Scanner(System.in);
try {
read=new BufferedReader(new InputStreamReader(client.getInputStream()));
write=new PrintWriter(client.getOutputStream(),true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true) {
try {
write.println(in.nextLine());
System.out.println(read.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Case2:读写同步
Case1中无论是服务器还是客户端,读写都不能同步,即读的时候不能写,写的时候不能读,这是由于读的中断机制(readLine()在没有读到完整信息时将线程中断wait()和单线程进程造成的。
进行修改:将读数据的操作单独放在一个独立的线程中,写数据操作仍然在主线程中,使得服务器端和客户端都可以同时读写。
服务器端
package FUXI;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ServerDemo2_FX {
public static void main(String[] args) {
int port=9999;
ServerSocket svr=null;
Socket socket=null;
try {
svr=new ServerSocket(port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//等待连接
try {
socket=svr.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ReadThreadDemo2_FX readThread=new ReadThreadDemo2_FX(socket,"服务器端读到客户端消息");
readThread.start();
PrintWriter write=null;
try {
write=new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Scanner in=new Scanner(System.in);
while(true) {
write.println(in.nextLine());
}
}
}
客户端
package FUXI;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientDemo2_FX {
public static void main(String[] args) {
//创建客户端,建立连接
String host="127.0.0.1";
int port=9999;
Socket client=null;
try {
client=new Socket(host,port);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//读写数据
ReadThreadDemo2_FX readThread=new ReadThreadDemo2_FX(client,"客户端读到服务器端消息");
readThread.start();
PrintWriter write=null;
Scanner in=new Scanner(System.in);
try {
write=new PrintWriter(client.getOutputStream(),true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true) {
write.println(in.nextLine());
}
}
}
读线程
package FUXI;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReadThreadDemo2_FX extends Thread {
Socket socket;
String name;
public void run() {
BufferedReader read=null;
try {
read=new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true) {
try {
System.out.println(name+":"+read.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public ReadThreadDemo2_FX(Socket socket,String name) {
this.socket=socket;
this.name=name;
}
}
Case3:服务器端可以和多个客户端数据交互
Case1,Case2中服务器端开启,accept方法使得服务器端主线程中断,等待客户端的连接请求,一旦和某个客户端连接上,则进入读写,服务器端无法再执行accept方法,这样就只允许一个客户端连接服务器端。解决办法:建立一个单独用于建立连接请求的线程,反复执行accept方法。注意:服务器端读取客户端发来的数据的读线程在连接请求线程中创建开启。读线程和Case2一样。
服务器端
package FUXI;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class ServerDemo3_FX {
public static Map<String,Socket> map=new HashMap<String,Socket>();
public static void main(String[] args) {
int port=9999;
ServerSocket svr=null;
try {
svr=new ServerSocket(port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
AcceptThreadDemo3_FX acceptThread =new AcceptThreadDemo3_FX(svr);
acceptThread.start(); //服务器端读取客户端的线程在AcceptThread中开启
//服务器端向客户端写的操作:每次向客户端发消息都先判断该客户端是否已连接,即是否在集合map中,是则取出对应的socket进行写数据操作
while(true) {
System.out.println("请输入你要发送数据的客户端的名称");
Scanner in=new Scanner(System.in);
String name=in.nextLine();
if(!map.containsKey(name))
{
System.out.println("你输入的名称不存在,请重新输入");
continue;
}
Socket socket=map.get(name);
System.out.println("请输入你想发送的数据:");
PrintWriter write=null;
try {
write=new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
write.println(in.nextLine());
}
}
}
客户端
package FUXI;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientDemo3_FX {
public static void main(String[] args) {
//创建客户端,建立连接
String host="127.0.0.1";
int port=9999;
Socket client=null;
try {
client=new Socket(host,port);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//读写数据
BufferedReader read=null;
//读取连接成功的信息,输入名字
try {
read=new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
System.out.println(read.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PrintWriter write=null;
Scanner in=new Scanner(System.in);
try {
write=new PrintWriter(client.getOutputStream(),true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
write.println(in.nextLine());//输入客户端名称
ReadThreadDemo2_FX readThread=new ReadThreadDemo2_FX(client,"客户端读到服务器端消息");
readThread.start();
while(true) {
write.println(in.nextLine());
}
}
}
AcceptThread线程
package FUXI;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class AcceptThreadDemo3_FX extends Thread{
ServerSocket svr;
public AcceptThreadDemo3_FX(ServerSocket svr){
this.svr=svr;
}
public void run() {
while(true) {
Socket socket=null;
try {
socket=svr.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader read=null;
PrintWriter write=null;
try {
read=new BufferedReader(new InputStreamReader(socket.getInputStream()));
write=new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//建立了连接请求客户端发给服务器端客户端的名称
write.println("收到连接请求,请发送你的名称");
String name="";
try {
name=read.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ServerDemo3_FX.map.put(name, socket);
//开启一条服务器端读取该name的客户端的读线程
ReadThreadDemo2_FX readThread=new ReadThreadDemo2_FX(socket,"服务器读取到"+name+"发送的数据");
readThread.start();
}
}
}