网络编程:TCP和UDP

传输协议

1、TCP:传输控制协议

2、UDP:用户数据报协议

TCP

面向连接的、安全可靠的,三次握手,性能较低

UDP

不建立连接、不可靠的、性能高、易丢包

Socket套接字:应用层与传输层的接口

10.网络编程(二) - 图1

UDP编程

概述

通信双方不需要建立连接

通信双方完全平等

QQ聊天模式

数据以包裹为中心:封包和拆包

方法

1、DatagramSocket:用于发送或者接受数据包的套接字

2、DatagramPacket:数据包:封包和拆包

使用对象

客户端:Client

接收端:Server

编写流程:Client端

每个进程具有一个或多个套接字,所以在目的主机指定特定的套接字是必要的。当生成一个套接字时,就为它分配一个端口号

1、使用DatagramSocket 指定端口创建发送端

2、准备数据转成字节数组

3、封装成DatagramPacket包裹,需要指定目的地(IP+端口)

4、发送包裹send(DatagramPacket p)

5、释放资源

代码片段

  1. /**
  2. * 发送端:Client
  3. * 1、使用DatagramSocket 指定端口创建发送端
  4. * 2、准备数据转成字节数组
  5. * 3、封装成DatagramPacket包裹,需要指定目的地(IP+端口)
  6. * 4、发送包裹send(DatagramPacket p)
  7. * 5、释放资源
  8. */
  9. public class UdpClient {
  10. public static void main(String[] args) throws Exception {
  11. System.out.println("发送方启动中......");
  12. //1、使用DatagramSocket对象 指定端口创建发送端
  13. DatagramSocket client=new DatagramSocket(8888);
  14. //准备数据转成字节数组
  15. String data="山东扒鸡,买一送一!";
  16. byte[]datas=data.getBytes();
  17. //3、封装成DatagramPacket包裹,需要指定目的地
  18. DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
  19. new InetSocketAddress("localhost",9999));
  20. //4、发送包裹send(DatagramPacket p)
  21. client.send(packet);
  22. //5、释放资源
  23. client.close();
  24. }
  25. }

编写流程:Server端

1、使用 DatagramSocket 指定端口创建接收端

2、准备容器封装成 DatagramPacket 包裹

3、阻塞式接受包裹 receive(DatagramPacket p)

4、分析数据 byte[]getData() ; getLength()

5、释放资源

代码片段

  1. /**
  2. * @auther TongFangPing
  3. * @date 2019/10/7 11:26.
  4. * 接收端
  5. * 1、使用DatagramSocket 指定端口创建接收端
  6. * 2、准备容器封装成DatagramPacket包裹
  7. * 3、阻塞式接受包裹receive(DatagramPacket p)
  8. * 4、分析数据
  9. * byte[]getData()
  10. * getLength()
  11. * 5、释放资源
  12. */
  13. public class UdpServer {
  14. public static void main(String[] args) throws Exception {
  15. System.out.println("接收方启动中......");
  16. //1、使用DatagramSocket 指定端口创建接收端
  17. DatagramSocket server=new DatagramSocket(9999);
  18. //2、准备容器封装成DatagramPacket包裹
  19. byte[]container=new byte[1024*60];
  20. DatagramPacket packet=new DatagramPacket(container,0,container.length);
  21. //3、阻塞式接受包裹receive(DatagramPacket p)
  22. server.receive(packet);
  23. //4、分析数据
  24. //byte[]getData()
  25. //getLength()
  26. byte[]datas=packet.getData();
  27. int len=datas.length;
  28. System.out.println(new String(datas,0,len));
  29. //5、释放资源
  30. }
  31. }

UDP案例(一):文件发送

  1. ** IOUtils
  2. * 文件(图片)的拷贝:
  3. * 文件——>程序——>字节数组——>文件
  4. */
  5. public class IOUtils {
  6. /**
  7. * 1、图片到字节数组:
  8. * 1、图片到程序:FileInputStream
  9. * 2、程序到字节数组:ByteArrayOutputStream
  10. */
  11. public static byte[] fileToByteArray(String path) {
  12. //创建源与目的地
  13. File src = new File(path);
  14. byte[] dest = null;
  15. //选择流
  16. InputStream is = null;
  17. ByteArrayOutputStream baos = null;
  18. try {
  19. is = new FileInputStream(src);
  20. baos = new ByteArrayOutputStream();
  21. //操作
  22. byte[] flush = new byte[1024 * 10];
  23. int len = -1;
  24. while ((len = is.read(flush)) != -1) {
  25. baos.write(flush, 0, len);
  26. }
  27. baos.flush();
  28. return baos.toByteArray();
  29. } catch (FileNotFoundException e) {
  30. e.printStackTrace();
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. }if(is!=null){
  34. try {
  35. is.close();
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. return null;
  41. }
  42. /**
  43. * 1、字节数组到文件
  44. * 1、字节数组到程序:ByteArrayInputStream
  45. * 2、程序到文件:FileOutputStream
  46. */
  47. public static void byteArrayToFile(byte[]src,String filePath){
  48. File dest=new File(filePath);
  49. InputStream is=null;
  50. OutputStream os=null;
  51. is=new ByteArrayInputStream(src);
  52. try {
  53. os=new FileOutputStream(dest);
  54. int len=-1;
  55. byte[]flush=new byte[10];
  56. while ((len=is.read(flush))!=-1){
  57. os.write(flush,0,len);
  58. }
  59. os.flush();
  60. } catch (FileNotFoundException e) {
  61. e.printStackTrace();
  62. } catch (IOException e) {
  63. e.printStackTrace();
  64. }
  65. if(os!=null){
  66. try {
  67. os.close();
  68. } catch (IOException e) {
  69. e.printStackTrace();
  70. }
  71. }
  72. }
  73. }
  1. /**
  2. *UdpFileClient类
  3. *文件上传:发送端
  4. * 发送图片文件
  5. * 图片文件大小不能太大
  6. */
  7. public class UdpFileClient {
  8. public static void main(String[] args) throws Exception {
  9. System.out.println("发送方启动中......");
  10. //1、使用DatagramSocket对象 指定端口创建发送端
  11. DatagramSocket client=new DatagramSocket(8888);
  12. //准备数据转成字节数组
  13. byte []datas=IOUtils.fileToByteArray("lib/img/QQ.png");
  14. //3、封装成DatagramPacket包裹,需要指定目的地
  15. DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
  16. new InetSocketAddress("localhost",9999));
  17. //4、发送包裹send(DatagramPacket p)
  18. client.send(packet);
  19. //5、释放资源
  20. client.close();
  21. }
  22. }
  1. /**
  2. * UdpFileServer类
  3. * 接收端:文件存储
  4. * 接收保存图片
  5. */
  6. public class UdpFileServer {
  7. public static void main(String[] args) throws Exception {
  8. System.out.println("接收方启动中......");
  9. //1、使用DatagramSocket 指定端口创建接收端
  10. DatagramSocket server=new DatagramSocket(9999);
  11. //2、准备容器封装成DatagramPacket包裹
  12. byte[]container=new byte[1024*60];
  13. DatagramPacket packet=new DatagramPacket(container,0,container.length);
  14. //3、阻塞式接受包裹receive(DatagramPacket p)
  15. server.receive(packet);
  16. //4、分析数据
  17. //byte[]getData()
  18. //getLength()
  19. byte[]datas=packet.getData();
  20. int len=datas.length;
  21. IOUtils.byteArrayToFile(datas,"lib/img/QQ_copy.png");
  22. //5、释放资源
  23. server.close();
  24. }
  25. }

UDP案例(二):聊天室

  1. /**
  2. * UdpTalkClient类
  3. * 多次交流:发送端
  4. * 1、使用DatagramSocket 指定端口创建发送端
  5. * 2、准备数据转成字节数组
  6. * 3、封装成DatagramPacket包裹,需要指定目的地(IP+端口)
  7. * 4、发送包裹send(DatagramPacket p)
  8. * 5、释放资源
  9. */
  10. public class UdpTalkClient {
  11. public static void main(String[] args) throws Exception {
  12. System.out.println("发送方启动中......");
  13. //1、使用DatagramSocket对象 指定端口创建发送端
  14. DatagramSocket client=new DatagramSocket(8888);
  15. //准备数据转成字节数组
  16. BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
  17. while (true){
  18. String data=reader.readLine();
  19. byte[]datas=data.getBytes();
  20. //3、封装成DatagramPacket包裹,需要指定目的地
  21. DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
  22. new InetSocketAddress("localhost",9999));
  23. //4、发送包裹send(DatagramPacket p)
  24. client.send(packet);
  25. if(data.equals("bye")){
  26. //System.out.println(Arrays.toString(data.getBytes()));
  27. break;
  28. }
  29. }
  30. //5、释放资源
  31. client.close();
  32. }
  33. }
  1. /**
  2. * UdpTalkServer类
  3. * 多次交流:接收端
  4. * 1、使用DatagramSocket 指定端口创建接收端
  5. * 2、准备容器封装成DatagramPacket包裹
  6. * 3、阻塞式接受包裹receive(DatagramPacket p)
  7. * 4、分析数据
  8. * byte[]getData()
  9. * getLength()
  10. * 5、释放资源
  11. */
  12. public class UdpTalkServer {
  13. public static void main(String[] args) throws Exception {
  14. System.out.println("接收方启动中......");
  15. //1、使用DatagramSocket 指定端口创建接收端
  16. DatagramSocket server=new DatagramSocket(9999);
  17. //2、准备容器封装成DatagramPacket包裹
  18. while (true){
  19. byte[]container=new byte[1024*60];
  20. DatagramPacket packet=new DatagramPacket(container,0,container.length);
  21. //3、阻塞式接受包裹receive(DatagramPacket p)
  22. server.receive(packet);
  23. //4、分析数据
  24. //byte[]getData()
  25. //getLength()
  26. byte[]datas=packet.getData();
  27. int len=datas.length;
  28. String data=new String(datas,0,len);
  29. System.out.println(data);
  30. //System.out.println(Arrays.toString(data.getBytes()));
  31. if(data.equals("bye")){
  32. break;
  33. }
  34. }
  35. //5、释放资源
  36. server.close();
  37. }
  38. }

UDP案例(三):多线程实现双向聊天

  1. /**
  2. * 加入多线程实现双向交流,模拟在线咨询
  3. * 学生端
  4. */
  5. public class TalkStudent {
  6. public static void main(String[] args) {
  7. new Thread(new UdpTalkSend(6666,"localhost",8888)).start();//发送
  8. new Thread(new UdpTalkReceive(9999,"马老师")).start(); //接收
  9. }
  10. }
  1. /**
  2. * 加入多线程实现双向交流,模拟在线咨询
  3. * 教师端
  4. */
  5. public class TalkTeacher {
  6. public static void main(String[] args) {
  7. new Thread(new UdpTalkReceive(8888,"扒鸡")).start(); //接收
  8. new Thread(new UdpTalkSend(5555,"localhost",9999)).start();//发送
  9. }
  10. }
  1. /**
  2. * 面向对象+多线程实现Talk
  3. * 发送端
  4. */
  5. public class UdpTalkSend implements Runnable{
  6. //1、使用DatagramSocket对象 指定端口创建发送端
  7. private DatagramSocket client;
  8. private BufferedReader reader;
  9. private String toIP;
  10. private int toPort;
  11. public UdpTalkSend(int port, String toIP, int toPort) {
  12. this.toIP=toIP;
  13. this.toPort=toPort;
  14. try {
  15. //1、使用DatagramSocket对象 指定端口创建发送端
  16. client=new DatagramSocket(port);
  17. //准备数据转成字节数组
  18. reader=new BufferedReader(new InputStreamReader(System.in));
  19. } catch (SocketException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. @Override
  24. public void run() {
  25. while (true){
  26. String data= null;
  27. try {
  28. data = reader.readLine();
  29. byte[]datas=data.getBytes();
  30. //3、封装成DatagramPacket包裹,需要指定目的地
  31. DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
  32. new InetSocketAddress(this.toIP,this.toPort));
  33. //4、发送包裹send(DatagramPacket p)
  34. client.send(packet);
  35. if(data.equals("bye")){
  36. //System.out.println(Arrays.toString(data.getBytes()));
  37. break;
  38. }
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. //5、释放资源
  44. client.close();
  45. }
  46. }
  1. /**
  2. * 接收端
  3. */
  4. public class UdpTalkReceive implements Runnable{
  5. private DatagramSocket server;
  6. private String from;
  7. public UdpTalkReceive(int port,String from) {
  8. this.from=from;
  9. try {
  10. //1、使用DatagramSocket 指定端口创建接收端
  11. server = new DatagramSocket(port);
  12. } catch (SocketException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. @Override
  17. public void run() {
  18. //2、准备容器封装成DatagramPacket包裹
  19. while (true){
  20. byte[]container=new byte[1024*60];
  21. DatagramPacket packet=new DatagramPacket(container,0,container.length);
  22. // 3、阻塞式接受包裹receive(DatagramPacket p)
  23. try {
  24. server.receive(packet);
  25. //4、分析数据
  26. byte[]datas=packet.getData();
  27. int len=packet.getLength();
  28. String data=new String(datas,0,len);
  29. System.out.println(from+": "+data);
  30. //System.out.println(Arrays.toString(data.getBytes()));
  31. if (data.equals("bye")){
  32. break;
  33. }
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. //5、释放资源
  39. server.close();
  40. }
  41. }

TCP编程

概述

通信双方需要建立连接请求—响应模式

连接建立时双方存在主次之分(第一次主动发起通讯的为客户端)

114查号台

利用IO流实现数据传输

Request和Response

10.网络编程(二) - 图2
10.网络编程(二) - 图3
10.网络编程(二) - 图4

编写流程:Client端

1、Socket对象(创建对象即建立连接:使用Socket创建客户端+服务的Ip地址和端口)

2、IO输入输出流(发送\接收消息)

3、关闭资源

代码片段

  1. /**
  2. * 创建客户端
  3. * 1、建立连接:使用Socket创建客户端+服务的Ip地址和端口
  4. * 2、操作:输入输出流操作
  5. * 3、释放资源
  6. */
  7. public class Client {
  8. public static void main(String[] args) throws IOException {
  9. System.out.println("------Client------");
  10. //1、建立TCP连接:使用Socket创建客户端+服务的Ip地址和端口(发起与服务端的TCP连接,用于3次握手)
  11. Socket client=new Socket("localhost",8888);
  12. //2、操作:输入输出流操作
  13. DataOutputStream dos=new DataOutputStream(client.getOutputStream());
  14. String msg="山东扒鸡,买一送一!";
  15. dos.writeUTF(msg);
  16. dos.flush();
  17. //3、释放资源
  18. dos.close();
  19. client.close();
  20. }
  21. }

编写流程:Server端

1、设置服务器监听对象(ServerSocket)

2、建立连接:Socket对象,接收一个客户端

3、阻塞式等待客户端连接:accept()方法

4、IO输入输出流,接收\返回消息

常用方法

**1、getInputStream():返回此套接字的输入流。

2、getOutputStream():返回此套接字的输出流。**

代码片段

  1. /**
  2. * 创建服务器
  3. * 1、指定端口 使用ServerSocket创建服务器
  4. * 2、阻塞式等待连接accept
  5. * 3、操作:输入输出流操作
  6. * 4、释放资源
  7. */
  8. public class Server {
  9. public static void main(String[] args) throws IOException {
  10. System.out.println("------Server------");
  11. //1、指定端口 使用ServerSocket创建服务器(建立了TCP套接字,用于和客户端Client的3次握手,也叫欢迎套接字)
  12. ServerSocket serverSocket=new ServerSocket(8888);
  13. //2、阻塞式等待连接accept,返回Socket对象,建立了一个新连接(新套接字:连接套接字)。
  14. Socket client=serverSocket.accept();
  15. System.out.println("一个客户端建立了连接。。。");
  16. //3、操作:输入输出流操作
  17. DataInputStream dis=new DataInputStream(client.getInputStream());
  18. String msg=dis.readUTF();
  19. System.out.println(msg);
  20. //4、释放资源
  21. dis.close();
  22. client.close();
  23. }
  24. }

TCP文件上传案例

  1. /**
  2. * 客户端
  3. * 上传文件
  4. * 1、建立连接:使用Socket创建客户端+服务的Ip地址和端口
  5. * 2、操作:输入输出流操作
  6. * 3、释放资源
  7. */
  8. public class FileClient {
  9. public static void main(String[] args) throws IOException {
  10. System.out.println("------Client------");
  11. //1、建立连接:使用Socket创建客户端+服务的Ip地址和端口
  12. Socket client=new Socket("localhost",8888);
  13. //2、操作:输入输出流操作(文件拷贝上传)
  14. InputStream is=new BufferedInputStream(new FileInputStream("lib/img/Socket.png"));
  15. OutputStream os=new BufferedOutputStream(client.getOutputStream());
  16. byte[]flush=new byte[1024];
  17. int len=-1;
  18. while ((len=is.read(flush))!=-1){
  19. os.write(flush,0,len);
  20. }
  21. os.flush();
  22. //3、释放资源
  23. os.close();
  24. is.close();
  25. client.close();
  26. }
  27. }
  1. /**
  2. * 服务端
  3. * 存储文件
  4. * 创建服务器
  5. * 1、指定端口 使用ServerSocket创建服务器
  6. * 2、阻塞式等待连接accept
  7. * 3、操作:输入输出流操作
  8. * 4、释放资源
  9. */
  10. public class FileServer {
  11. public static void main(String[] args) throws IOException {
  12. System.out.println("------Server------");
  13. //1、指定端口 使用ServerSocket创建服务器
  14. ServerSocket serverSocket=new ServerSocket(8888);
  15. //2、阻塞式等待连接accept,返回Socket对象,建立了连接。
  16. Socket client=serverSocket.accept();
  17. System.out.println("一个客户端建立了连接。。。");
  18. //3、操作:输入输出流操作 (文件拷贝存储)
  19. InputStream is=new BufferedInputStream(client.getInputStream());
  20. OutputStream os=new BufferedOutputStream(new FileOutputStream("lib/img/Socket_copy.png"));
  21. byte[]flush=new byte[1024];
  22. int len=-1;
  23. while ((len=is.read(flush))!=-1){
  24. os.write(flush,0,len);
  25. }
  26. os.flush();
  27. //4、释放资源
  28. os.close();
  29. is.close();
  30. client.close();
  31. }
  32. }

模拟登录案例

  1. /**
  2. * 模拟登录(双向)
  3. * 创建客户端
  4. * 1、建立连接:使用Socket创建客户端+服务的Ip地址和端口
  5. * 2、操作:输入输出流操作
  6. * 3、释放资源
  7. */
  8. public class LoginClient {
  9. public static void main(String[] args) throws IOException {
  10. //1、建立连接:使用Socket创建客户端+服务的Ip地址和端口
  11. Socket client=new Socket("Localhost",5555);
  12. BufferedReader console=new BufferedReader(new InputStreamReader(System.in));
  13. System.out.println("请输入用户名:");
  14. String uname=console.readLine();
  15. System.out.println("请输入密码:");
  16. String upwd=console.readLine();
  17. //2、操作:输入输出流操作
  18. DataOutputStream dos=new DataOutputStream(client.getOutputStream());
  19. dos.writeUTF("uname="+uname+"&"+"upwd="+upwd);
  20. dos.flush();
  21. DataInputStream dis=new DataInputStream(client.getInputStream());
  22. String result=dis.readUTF();
  23. System.out.println(result);
  24. //3、释放资源
  25. dos.close();
  26. dis.close();
  27. client.close();
  28. }
  29. }
  1. /**
  2. * 模拟登录(双向)
  3. * 创建服务器
  4. * 1、指定端口 使用ServerSocket创建服务器
  5. * 2、阻塞式等待连接accept
  6. * 3、操作:输入输出流操作
  7. * 4、释放资源
  8. */
  9. public class LoginServer {
  10. public static void main(String[] args) throws IOException {
  11. //1、指定端口 使用ServerSocket创建服务器
  12. ServerSocket server=new ServerSocket(5555);
  13. //2、阻塞式等待连接accept
  14. Socket client=server.accept();
  15. System.out.println("一个客户建立了连接");
  16. //3、操作:输入输出流操作
  17. DataInputStream dis=new DataInputStream(client.getInputStream());
  18. String datas=dis.readUTF();
  19. String uname="";
  20. String upwd="";
  21. //4、分析数据
  22. String[]dataArray=datas.split("&");
  23. for(String info:dataArray){
  24. String[]userInfo=info.split("=");
  25. if(userInfo[0].equals("uname")){
  26. uname=userInfo[1];
  27. System.out.println("你的用户名是:"+userInfo[1]);
  28. }else if(userInfo[0].equals("upwd")){
  29. upwd=userInfo[1];
  30. System.out.println("你的密码是:"+userInfo[1]);
  31. }
  32. }
  33. DataOutputStream dos=new DataOutputStream(client.getOutputStream());
  34. if(uname.equals("扒鸡")&&upwd.equals("123")){ //验证成功
  35. dos.writeUTF("登录成功,欢迎回来!");
  36. }else{ //验证失败
  37. dos.writeUTF("密码或者用户名错误!");
  38. }
  39. dos.flush();
  40. //5、释放资源
  41. dis.close();
  42. client.close();
  43. }
  44. }

模拟登录(双向)+多个客户端请求

  1. /**
  2. * 模拟登录(双向)+多个客户端请求
  3. * 创建客户端
  4. * 1、建立连接:使用Socket创建客户端+服务的Ip地址和端口
  5. * 2、操作:输入输出流操作
  6. * 3、释放资源
  7. */
  8. public class LoginMultiClient {
  9. public static void main(String[] args) throws IOException {
  10. //1、建立连接:使用Socket创建客户端+服务的Ip地址和端口
  11. System.out.println("------Client------");
  12. Socket client=new Socket("Localhost",5555);
  13. new Send(client).send();
  14. new Receive(client).receive();
  15. client.close();
  16. }
  17. //发送数据
  18. static class Send{
  19. private Socket client;
  20. private DataOutputStream dos;
  21. private BufferedReader console;
  22. private String msg;
  23. public Send(Socket client) {
  24. console=new BufferedReader(new InputStreamReader(System.in));
  25. this.msg=init();
  26. this.client = client;
  27. try {
  28. dos=new DataOutputStream(client.getOutputStream());
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. //初始化
  34. private String init(){
  35. try {
  36. System.out.println("请输入用户名:");
  37. String uname=console.readLine();
  38. System.out.println("请输入密码:");
  39. String upwd=console.readLine();
  40. return "uname="+uname+"&"+"upwd="+upwd;
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. return null;
  45. }
  46. private void send(){
  47. try {
  48. dos.writeUTF(msg);
  49. dos.flush();
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
  55. //接收数据
  56. static class Receive{
  57. private Socket client;
  58. private DataInputStream dis;
  59. public Receive(Socket client) {
  60. this.client = client;
  61. try {
  62. dis=new DataInputStream(client.getInputStream());
  63. } catch (IOException e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. public void receive(){
  68. String result= null;
  69. try {
  70. result = dis.readUTF();
  71. } catch (IOException e) {
  72. e.printStackTrace();
  73. }
  74. System.out.println(result);
  75. }
  76. }
  77. }
  1. /**
  2. * 模拟登录(双向)+多个客户端请求
  3. * 创建服务器
  4. * 1、指定端口 使用ServerSocket创建服务器
  5. * 2、阻塞式等待连接accept
  6. * 3、操作:输入输出流操作
  7. * 4、释放资源
  8. */
  9. public class LoginMultiServer {
  10. public static void main(String[] args) throws IOException {
  11. System.out.println("------Server------");
  12. //创建服务器,监听端口
  13. ServerSocket server=new ServerSocket(5555);
  14. Boolean isRunning=true;
  15. while (isRunning){
  16. Socket client=server.accept();
  17. System.out.println("一个客户建立了连接");
  18. new Thread(new Channel(client)).start();
  19. }
  20. server.close();
  21. }
  22. //一个Channel就代表了一个客户端
  23. static class Channel implements Runnable{
  24. private Socket client;
  25. //输入流
  26. private DataInputStream dis;
  27. //输出流
  28. private DataOutputStream dos;
  29. //构造器
  30. public Channel(Socket client) {
  31. this.client=client;
  32. try{
  33. //输入
  34. dis=new DataInputStream(client.getInputStream());
  35. //输出
  36. dos=new DataOutputStream(client.getOutputStream());
  37. }catch (IOException e) {
  38. e.printStackTrace();
  39. release();
  40. }
  41. }
  42. //接收数据
  43. private String Receive(){
  44. String datas = null;
  45. try {
  46. datas = dis.readUTF();
  47. } catch (IOException e) {
  48. e.printStackTrace();
  49. }
  50. return datas;
  51. }
  52. //发送数据
  53. private void send(String msg){
  54. try {
  55. dos.writeUTF(msg);
  56. dos.flush();
  57. } catch (IOException e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. //释放资源
  62. private void release(){
  63. try {
  64. if(null!=dis){
  65. dis.close();
  66. }
  67. } catch (IOException e) {
  68. e.printStackTrace();
  69. }
  70. try {
  71. if(null!=dos){
  72. dos.close();
  73. }
  74. } catch (IOException e) {
  75. e.printStackTrace();
  76. }
  77. try {
  78. if(null!=client){
  79. client.close();
  80. }
  81. } catch (IOException e) {
  82. e.printStackTrace();
  83. }
  84. }
  85. @Override
  86. public void run() {
  87. String uname="";
  88. String upwd="";
  89. //4、分析数据
  90. String[]dataArray=Receive().split("&");
  91. for(String info:dataArray){
  92. String[]userInfo=info.split("=");
  93. if(userInfo[0].equals("uname")){
  94. uname=userInfo[1];
  95. System.out.println("你的用户名是:"+userInfo[1]);
  96. }else if(userInfo[0].equals("upwd")){
  97. upwd=userInfo[1];
  98. System.out.println("你的密码是:"+userInfo[1]);
  99. }
  100. }
  101. if(uname.equals("扒鸡")&&upwd.equals("123")){ //验证成功
  102. send("登录成功,欢迎回来!");
  103. }else{ //验证失败
  104. send("密码或者用户名错误!");
  105. }
  106. //释放资源
  107. release();
  108. }
  109. }
  110. }