C/S模型:TCP,UDP构建客户端和服务器端应用测试
ava中提供了socket编程来构建客户端和服务器端
TCP
构建服务器端的步骤:
(1)bind:绑定端口号
(2)listen:监听客户端的连接请求
(3)accept:返回和客户端连接的实例
(4)read/write:进行读写操作,也就是和客户端进行交互
(5)close:关闭资源
Java中提供了ServiceSocket关键字来构建服务器,在Java中listen和accept合并为一个accept操作,下面通过代码演示一下这5个步骤
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket();
//bind:绑定ip和端口
serverSocket.bind(new InetSocketAddress(6666));
//listen监听并且accpet返回socket实例
Socket accept = serverSocket.accept();
//通过socket拿到输入流和输出流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
PrintStream printStream = new PrintStream(accept.getOutputStream());
//读到客户端发来的数据并打印
String s = bufferedReader.readLine();
System.out.println("收到客户端的数据:"+s);
//向客户端输出数据
printStream.println("啦啦啦啦服务器回消息:"+s);
//关闭流和socket
printStream.close();
bufferedReader.close();
serverSocket.close();
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket();
//bind:绑定ip和端口
serverSocket.bind(new InetSocketAddress(6666));
//listen监听并且accpet返回socket实例
Socket accept = serverSocket.accept();
//通过socket拿到输入流和输出流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
PrintStream printStream = new PrintStream(accept.getOutputStream());
//读到客户端发来的数据并打印
String s = bufferedReader.readLine();
System.out.println("收到客户端的数据:"+s);
//向客户端输出数据
printStream.println("啦啦啦啦服务器回消息:"+s);
//关闭流和socket
printStream.close();
bufferedReader.close();
serverSocket.close();
}
}
构建客户端的步骤:
(1)connect:通过IP地址和端口号连接服务器端
(2)read/write:进行读写操作,也就是和服务器端进行信息交流
(3)close:关闭资源
可以看到相比于服务器端,客户端的操作要简单很多
由于我们写的是TCP协议下的,所以要先启动服务器端,服务器端启动后,在accept会等待客户端的连接,也就是说代码在这里会阻塞住,客户端在这个时候连接就可以了。
下面用代码演示一下这几个步骤:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket();
//bind:绑定ip和端口
serverSocket.bind(new InetSocketAddress(6666));
//listen监听并且accpet返回socket实例
Socket accept = serverSocket.accept();
//通过socket拿到输入流和输出流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
PrintStream printStream = new PrintStream(accept.getOutputStream());
//读到客户端发来的数据并打印
String s = bufferedReader.readLine();
System.out.println("收到客户端的数据:"+s);
//向客户端输出数据
printStream.println("啦啦啦啦服务器回消息:"+s);
//关闭流和socket
printStream.close();
bufferedReader.close();
serverSocket.close();
}
}
这两个demo都用到了缓冲流和打印流来进行读写操作,下面看一下运行的结果
收录吧目录 银徽分类目录博客分类目录优化分类目录 外链站分类目录天宇吧分类目录114分类目录网址分类目录 十堰分类目录 103分类目录 小五分类目录669分类目录七九分类目录链录分类目录艾录分类目录九八分类目录爱站分类目录29分类目录001分类目录优站分类目录分类目录网第一分类目录35分类目录 站长目录壹网分类目录易收分类目录 西园分类目录 优能分类目录 尼尼分类目录艺术分类目录逍遥分类目录
面想一个需求,如果是多个客户端和服务器端进行信息的交流怎么办?
刚才已经提到了,服务器端accpet操作是等待客户端连接的操作,那么写一个循环,每一个循环体里面有一个accept不就可以解决多个客户端连接服务器端的问题了,但是要注意一点的是accpet是一个阻塞操作,所以需要多个线程才可以,下面解释一下为什么:
首先需要明白的是只需要对服务器端进行修改即可,所以这块都是针对服务器端说的
如果只有一个线程,那么通过accpet连接上,那么这个线程还要用啦进行读写,在读写的时候也会阻塞,如果读写的时候阻塞了,那么下一个accpet就是不能正常连接的,线程就一直停到第一个连接上了,直到该连接完毕结束后才可以下一个连接,很明显这个过程是一个串行的过程,达不到所要的效果,这就需要多线程,主线程只用来保持连接(accpet),然后子线程负责和客户端进行读写交互,这样的话子线程在读写阻塞的时候是不会影响到主线程的。
下面先来看看多个客户端一个服务器端的代码:
下面的代码只展示服务器端,客户端和上面保持不变
需要说明的几点:
(1)这块我用到了线程池,不用多次创建线程,方便统一管理并且高效。也可以单独创建多个线程,通过循环也是可以的。
(2)我写了一个MyThread类专门用来处理读写和客户端的信息交流,也就是子线程完成读写操作,主线程只用关心和服务器端的连接即可。
(3)用完资源后必须关闭,并且尽量不要抛异常,在当前方法中处理一下。
UDP
UDP不像TCP是可靠的连接,也就是会保证数据的正确送达,而UDP会以数据报的形式扩散数据,举一个很简单的例子:听广播,当节目到达时必须提前打开收音机,这样才会保证不会错过。UDP也是一样,服务器端发送数据时,客户端需要提前等着,以免错过数据。
UDP完成客户端和服务器端需要两个类:DatagramPacket和DatagramSocket
DatagramSocket是建立连接的套接字,可以理解为运送货物的码头
DatagramPacket是数据包,也就是说数据在传送过程中是被打包成了数据包,如果DatagramSocket是码头,那么DatagramPacket就是装载货物的箱子。