- ServerSocket 类 : 是一个封装支持TCP协议的操作类,主要工作在服务器端,用于接收客户端请求;
- Socket 类:是一个封装了 TCP 协议的操作类,每一个Socket 对象都表示了一个客户端
ServerSocket类常用操作方法:
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public ServerSocket( int port) throws IOException | 构造 | 开辟一个指定的端口监听,一般使用5000以上 |
2 | public Socket accept() throws IOException | 普通 | 服务器端接收客户端请求,通过Socket 返回 |
3 | public void close() throws IOException | 普通 | 关闭服务器 |
Socket 类的常用操作方法:
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public Socket(String host , int port) throws UnknowHostException,IOException | 构造 | 指定要连接的主机(IP地址)和端口 |
2 | public OutputSteam getOutputStream() throws IOException | 普通 | 取得指定客户端的输出对象,使用时肯定使用 PrintStream 装饰操作 |
3 | public InputStream getInputStream() throws IOException | 普通 | 从指定的客户端读取数据,使用 Scanner 操作 |
eg : 完成一个服务器端程序代码
package MyExample;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class HelloServer {
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(9999);//在9999端口监听
System.out.println("服务开始启动...");
Socket client = server.accept();//接收客户端连接,进入阻塞状态
PrintStream out = new PrintStream(client.getOutputStream());
out.println("Hello World.");//向客户端输出
out.close();//输出流关闭
client.close();//关闭客户端
server.close();//关闭服务端
System.out.println("服务器已关闭...");
}
}
使用 cmd telnet 测试
(1)使用运行方式输入 : telnet
(2)连接服务器: open ip地址 端口,open localhost 9999
eg : 编写一个客户端
package MyExample;
import java.net.Socket;
import java.util.Scanner;
public class HelloClient {
public static void main(String[] args) throws Exception{
Socket client = new Socket("localhost",9999);//连接服务器及端口
Scanner scan = new Scanner(client.getInputStream());//取得客户端输入流
scan.useDelimiter("\n"); //将分隔符改为回车
if(scan.hasNext()){
System.out.println("服务器的回应数据: " + scan.next());
}
scan.close();
client.close();
}
}
经典模型–ECHO程序
回应程序,即客户端输入哪些内容,服务器端会在这些内容前加上“ECHO:”并将信息发回客户端。
eg:编写一个程序的基本模型
package MyExample;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class EchoServer {
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(9999);//定义监听端口
boolean flag = true;//运行标记
System.out.println("服务器运行...");
Socket client = server.accept();//接收客户端请求
Scanner scan = new Scanner(client.getInputStream());
PrintStream out = new PrintStream(client.getOutputStream());
out.println("服务器开始准备接收消息了...");
while(flag){
if(scan.hasNext()){//有内容
String str = scan.next();
if("byebye".equalsIgnoreCase(str.trim())){//程序结束
out.println("Bye Bye...");
flag = false;//退出循环
}
out.println("ECHO:"+str.trim());
}
}
System.out.println("服务器停止运行...");
server.close();
}
}
eg:为服务器端增加多线程机制,使用匿名内部类
package MyExample;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class EchoServerThread {
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(9999);
boolean flag = true;
System.out.println("服务期开始运行...");
while(flag){
final Socket client = server.accept();
new Thread(new Runnable(){
@Override
public void run(){
boolean runFlag = true;//运行标记
try{
Scanner scan = new Scanner(client.getInputStream());
PrintStream out = new PrintStream(client.getOutputStream());
while(runFlag){
if(scan.hasNext()){
String str = scan.next();
if("byebye".equalsIgnoreCase(str.trim())){
out.println("Bye Bye...");
runFlag = false;
}
out.println("ECHO: " + str.trim());
}
}
}catch(IOException e){
e.printStackTrace();
}
try{
client.close();
}catch(IOException e){
e.printStackTrace();
}
}
}).start();
}
System.out.println("服务器停止运行...");
server.close();
}
}