我调试了一下,客户端的socket.shutdownOutput()会触发serverSocket.accept();可是服务器线程是如何保证在向客户端写入“欢迎你”后客户端才会进行数据流的读入。求解。。。。
accept()方法是服务器端方法,是用来监听某个端口是否收到连接请求,这都没建立连接呢,发送啥数据。
至于说客户端获得服务器的响应,那是连接建立之后,getInputStream()方法可以获取输入流,这个方法是阻塞的,就是调用之后会一直等待数据到来。
客户端和服务器的socket你都没搞清楚吧!
客户端socket.shutdownOutput()之后,服务器知道这个客户端不会再发送数据了,如果服务器的数据也已经发送完毕,连接就会断开,服务器重新调用accept()方法,继续监听端口。
楼上正解
以前再学校里面学过一点点socket,现在听过老师讲的课后又编写了一遍,不知道实际的开发中是不是这样用线程去等待接受别人发送信息
package test;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ServerSocket {
public static void main(String[] args) throws UnknownHostException, IOException{
java.net.ServerSocket server=new java.net.ServerSocket(10);
List list=new ArrayList();
while(true){
Socket socket= server.accept();
list.add(new Session(socket));
/*OutputStream output= socket.getOutputStream();
ObjectOutputStream objout=new ObjectOutputStream(output);
objout.writeObject(list);*/
}
}
}
class Session extends Thread{
private Socket sck;
private User u;
public Session(Socket sck) throws IOException{
this.sck=sck;
Scanner sc=new Scanner(System.in);
try {
InputStream input= sck.getInputStream();
ObjectInputStream objInput=new ObjectInputStream(input);
this.u=(User)objInput.readObject();
System.out.println("当前用户:"+u.getName());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.start();
OutputStream output=this.sck.getOutputStream();
while(true){
System.out.print("您说:");
String mesg= sc.nextLine();
output.write(("\n"+mesg).getBytes());
}
}
@Override
public void run() {
while(true){
InputStream input=null;
int length=0;
try {
input = sck.getInputStream();
length= input.available();
byte[] b=new byte[length];
input.read(b);
String str=new String(b);
if(str!=null&&!str.isEmpty()){
System.out.println("\n"+u.getName()+"说:"+str);
}
this.sleep(100);
} catch (IOException e) {
try {
input.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这是服务器端代码
package test;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Scanner;
public class ClinetSocket extends Thread {
private Socket socket;
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException{
new ClinetSocket().login();
}
public void login() throws UnknownHostException, IOException, ClassNotFoundException{
Scanner sc=new Scanner(System.in);
System.out.print("请输入您的昵称:");
User u= new User(sc.nextLine());
Socket socket=new Socket("127.0.0.1", 10);
OutputStream output= socket.getOutputStream();
ObjectOutputStream objout=new ObjectOutputStream(output);
objout.writeObject(u);
this.socket=socket;
this.start();
/*while(true){
InputStream input= socket.getInputStream();
ObjectInputStream objInput=new ObjectInputStream(input);
List list= (List)objInput.readObject();
if(list!==null&&!list.isEmpty()){
System.out.println("当前在线用户:");
for(int i=0;i<list.size();i++){
}
}
}*/
while(true){
System.out.print("您说:");
String mesg= sc.nextLine();
output.write(mesg.getBytes());
}
}
public void run(){
InputStream input=null;
try {
input= this.socket.getInputStream();
while(true){
byte[] b=new byte[input.available()];
input.read(b);
if(b.length>0){
System.out.println("\n"+new String(b));
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class User implements Serializable{
private String name;
public User(String name){
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这是客户端代码
我在客户端使用一个线程去无限循环执行这样的一段代码获取服务器端发送的消息
public void run(){
InputStream input=null;
try {
input= this.socket.getInputStream();
while(true){
byte[] b=new byte[input.available()];
input.read(b);
if(b.length>0){
System.out.println("\n"+new String(b));
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
不知道这么做是不是不合适
info = br.readLine()
客户端线程是在这行代码停下的,不知道具体是为啥,具体是哪个方法实现的阻塞?求。。。