1.TCP程序 - C/S
需要使用到两个类,来编写TCP的C/S程序:
1. ServerSocket 搭建服务器,连接客户端
2. Socket 搭建客户端,连接服务器
两方使用Socket(套接字,通信端点)进行交流
明确一点,在进行网络编程时,一定是先有服务器,客户端再去连服务器。以后写肯定都有两个Demo(两个main线程),一个是连服务器的,一个是连客户端的。
1.1ServerSocket
1. 用于创建服务器,创建完毕以后,会绑定一个端口号;
2. 然后此服务器可以等待客户端连接;
3. 每连接一个客户端,服务器就会得到一个新的Socket对象,用于跟客户端进行通信。
ServiceSocket类的常用构造方法:
ServerSocket(int port);//传入指定的端口号port
创建一个基于TCP/IP协议的服务器,并绑定指定的端口号,
注意:参数port的范围是:0-65535,建议(1025-65535)
ServerSocket的构造方法
构造器 | 描述 |
---|---|
ServerSocket() | 创建未绑定服务的 套接字 |
ServerSocket(int port) | 创建绑定到指定端口的服务器 套接字 |
ServerSocket(int port,int backlog) | 创建服务器套接字 并 使用指定的待办事项将其绑定到指定的本地端口 |
ServerSocket(int port,int backlog,InetAddress bindAddr) | 创建具有指定端口的服务器,监听backlog和要绑定的本地IP地址 |
方法很多,有需求可以查看API,常用方法有如下
Soket accept();
等待客户端连接,
此方法会导致线程阻塞,
直到一个新的客户端连接成功,return Socket对象后,线程继续执行
void close();
释放占用的端口,关闭服务器。就会执行四次挥手操作,稳稳地关闭服务器
变量和类型 | 方法 | 描述 |
---|---|---|
Socket | accept() | 侦听对此套接字的连接并接受它 |
void | close() | 关闭此套接字 |
InetAddress | getInetAdress() | 返回此服务器套接字的本地地址 |
boolean | isClosed() | 返回ServerSocket的关闭状态 |
… | … | … |
1.2Socket类
是两台计算机之间的通信的端点,是网络驱动提供给应用程序的一种接口,一套标准,一种机制。
常用构造方法:
Socket(String ip,it port);
创建一个 套接字,并连接指定ip和端口号的 服务器
参数1. 服务器ip地址
参数2. 服务器软件的端口号
连接靠两个Demo实现,先创建服务器端,后创建客户端
//服务器
public class Demo {
public static void main(String[] args) throws IOException {
//搭建服务器,写入端口号
ServerSocket serverSocket = new ServerSocket(55533);
//等待客户端连接,会阻塞,直到一个客户端连接成功
Socket socket = serverSocket.accept();
System.out.println("服务器程序执行结束");
}
}
必须先运行以上代码后,运行下面代码才能连接
//客户端
public class ClientDemo {
public static void main(String[] args) throws IOException {
//本机的IP地址默认为 127.0.0.1
Socket socket = new Socket("127.0.0.1",55533);
}
}
Socket类的常用方法
1.OutputStream getOutputStream();
返回的是,指向通信的另一端点的输出流
2.InputStream getInputSream();
返回的是,指向通信的另一端点的输入流
3.void close();
关闭 套接字
注意:
1. 在网络编程时,获取输入流的操作,对于客户端与服务器来说是相对的
2. 客户端的输入流,输入的是服务器的输出流 输出的内容
3. 客户端的输出流,输出的是服务器的输入流,
所以,在使用时,需要注意以下一点规则:
客户端与服务器获取流的顺序必须是相反的,只能是一端收一段发,不同两端都发/收,否则会卡在这;
但是可以选择多线程进行,一个接收一个发送同时将进行。
例如:客户端先得到了输入流,那服务器端必须先获取输出流
使用最多的还是getInputStream()/getOutputStream()方法
变量和类型 | 方法 | 描述 |
---|---|---|
void | close() | |
InputStream | getInputStream() | 返回套接字的输入流 |
OutputStream | getOutputStream() | 返回此套接字的输出流 |
int | getPort() | 返回此套接字的远程端口号 |
boolean | isBound() | 返回套接字的绑定状态 |
boolean | isClosed() | 返回套接字的连接状态 |
boolean | isConnected() | 返回套接字的连接状态 |
… | … | … |
代码演示:
//服务器端
public class Demo {
public static void main(String[] args) throws IOException {
//搭建服务器,ServerSocket()需要传入 端口号(0-65565)
ServerSocket serverSocket = new ServerSocket(55533);
System.out.println("服务器启动完毕");
//等待客户端连接,会阻塞,直到一个客户端连接成功
Socket socket = serverSocket.accept();
System.out.println("一个客户端连接了");
//获取一个输出流
OutputStream os = socket.getOutputStream();
//把输出流转换为打印流,转换为打印流是为了可以输入一串字符
PrintStream ps = new PrintStream(os);
//给客户端发送消息
ps.println("客户端你好");
//接收
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String txet = br.readLine();
System.out.println("服务器端接收的信息:"+txet);
System.out.println("服务器程序执行结束");
}
}
//客户端
public class ClientDemo {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1",55533);
InputStream is = socket.getInputStream();
//使用BufferedReader接收可以一次接收一行
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String text = br.readLine();
System.out.println("客户端接收到消息:"+text);
//发送
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.println("服务器你好");
}
}
1.3在服务器中加入多线程
在连接以后进行的操作必须执行完毕才能再回去连接客户端,比如sleep(),只有sleep()执行完毕以后服务器端才能连接客户端
服务器能同时服务多个客户端怎么办,使用循环等待客户端连接必不可少。注意客户端与服务器端必须是一端输入一端接收的机制
//就不进行接收演示了,就是接 收,交替执行
public class Demo {
public static void main(String[] args) throws IOException {
//搭建服务器
ServerSocket serverSocket = new ServerSocket(55533);
System.out.println("服务器启动完毕");
while (true) {
//等待客户端连接,会阻塞,直到一个客户端连接成功
//服务器可以抗住很多的客户端
Socket socket = serverSocket.accept();
// 启动一个子线程与客户端进行交互,无限循环就无限启动子线程,主线程就能一直等待客户端连接
// 提高服务器的处理多个客户端的能力
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
System.out.println("一个客户端连接了");
}
}
}