依据TCP协议,在C/S架构的通讯过程中,客户端和服务器的Socket动作如下
服务器:
1. 在服务器,用一个端口来实例化一个 ServerSocket对象。此时,服务器就可以这个端口时刻监听从客户端发来的连接请求。
2.调用ServerSocket的accept方法,开始监听连接从端口上发来的连接请求。
3.利用accept方法返回的客户端的Socket对象,进行读写IO的操作
通讯完成后,关闭打开的流和Socket对象。
public class Server {
//端口号
public static int PORTNO = 8888;
public static void main(String[] args) throws IOException {
//初始化ServerSocket对象,承担服务器端监听连接和提供通讯服务的功能
ServerSocket s = new ServerSocket(PORTNO);
System.out.println("服务启动"+s);
//调用ServerSocket对象的accept方法,监听从客户端的连接请求。
//当完成调用accept方法后,整段服务器端代码将会阻塞在这里,直到客户端发来connect请求
//当客户端发来connect请求,或是通过构造函数直接把客户端的socket对象连接到服务器端后,
//阻塞于此的代码将会继续运行。此时服务器端将会根据accept方法的执行结果,用一个socket对象来描述客户端的连接句柄
Socket socket = s.accept();
try {
System.out.println("accept the client:"+socket);
//创建in out对象,分别用来传输和接收通讯时的数据流
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
//创建一个while(true)的死循环,在循环里通过in.readLine()方法读取从客户端发送过来的IO流,并打印出来,如果读到的字符串是“byebye”,那么退出循环
while(true){
String str = in.readLine();
if(str.endsWith("byebye")){
break;
}
System.out.println("in service reveived the info:"+str);
out.println(str);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
System.out.println("close the server socket and the io.");
//关闭描述客户端的连接句柄socket对象和ServerSocket类型的s对象
socket.close();
s.close();
}
}
}
客户端:
1.用服务器的IP地址和端口号实例化Socket对象。
2.调用connect方法,连接到服务器上。
3.将发送到服务器的IO流填充到IO对象里,比如BufferedReader/PrintWriter
4.利用Socket提供的getInputStream和getOutputStream方法,通过IO流对象,向服务器发送数据流。
5. 通讯完成后,关闭打开的IO对象和Socket。
public class Client {
static String CLIENTNAME = "mike";
//定义通讯端口号,这里给出的端口号必须和服务器端的一致
public static int PORTNO = 8888;
public static void main(String[] args) throws IOException {
//根据地址信息localhost创建一个InetAddress类型的对象addr。
//我们把客户端和服务器端的代码都在本机运行,所以同样可以用"127.0.0.1"字符串,来创建inetaddress对象
InetAddress addr = InetAddress.getByName("localhost");
//根据addr和端口号信息,创建一个socket类对象,该对象用来同服务器端的Serversocket类型对象交互,共同完成C/S通讯流程
Socket socket = new Socket(addr,PORTNO);
try {
System.out.println("socket = "+socket);
//同样创建in和out两类IO句柄,用来向服务器端发送和接收数据流
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//通过out对象像服务器端发送"hello server,i am ..."字符串。发送后,同样可以用in句柄,接收从服务器端的消息
out.println("hello server,i am "+CLIENTNAME);
String str= in.readLine();
System.out.println(str);
//利用out对象,发送“byebye”字符串,用以告知服务器端,本次通讯结束
out.println("byebye");
} catch (Exception e) {
}finally{
System.out.println("close the client socket and the io.");
//关闭socket对象,断开同服务器端的连接
socket.close();
}
}
}
先开启服务器端的程序再开启客户端,如果这个步骤做反的话,客户端程序会应找不到服务器端而报异常