socket通信

 
IP地址和端口号组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础。
 
Java中对于网络通信的支持主要包含以下四大类:
 
    1.InetAddress:用于标识网络上的硬件资源。说白了就是标识IP等。
 
    2.URL:统一资源定位符,通过URL可以直接读取或写入网络上的数据。
 
    3.Sockets:使用TCP协议实现网络通信的Socket相关的类。
 
    4.Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信。
 
    简单的两个DEMO,介绍java中的InetAddress类和URL类。
    介绍InetAddress类:
  1. package com.wang;
  2. import java.net.InetAddress;
  3. import java.net.UnknownHostException;
  4. import java.util.Arrays;
  5. publicclassInetAddressTest{
  6. publicstaticvoid main(String[] args)throwsUnknownHostException{
  7. InetAddress localhost =InetAddress.getLocalHost();
  8. System.out.println("localhost:"+ localhost);
  9. InetAddress address =InetAddress.getByName("wangdaye-PC");
  10. System.out.println(address.getHostAddress()+"="+ address.getHostName());
  11. byte[] bytes = address.getAddress();
  12. System.out.println("字节数组:"+Arrays.toString(bytes));
  13. System.out.println(address);
  14. }
  15. }
    介绍URL类:
    
  1. package com.wang;
  2. import java.io.BufferedReader;
  3. import java.io.InputStream;
  4. import java.io.InputStreamReader;
  5. import java.net.URL;
  6. /**
  7. * 端口号未指定,默认为80,getPort()函数返回值为-1
  8. * @author wangdaye
  9. */
  10. publicclassURLTest{
  11. publicstaticvoid main(String[] args)throwsException{
  12. URL testUrl =new URL("http://www.sina.com:80/sb/index.jsp");
  13. // System.out.println(testUrl.getPort());
  14. URL url =new URL(testUrl,"wang");
  15. System.out.println("协议:"+ url.getProtocol());
  16. System.out.println("主机名:"+ url.getHost());
  17. System.out.println("端口:"+ url.getPort());
  18. System.out.println("文件路径:"+ url.getPath());
  19. System.out.println("文件名称:"+ url.getFile());
  20. System.out.println("相对路径:"+ url.getRef());
  21. System.out.println("查询字符串:"+ url.getQuery());
  22. //读取网络资源的内容
  23. URL baidu =new URL("http://www.baidu.com:80/sb/index.jsp");
  24. InputStream inputStream = baidu.openStream();
  25. InputStreamReader reader =newInputStreamReader(inputStream);
  26. BufferedReader br =newBufferedReader(reader);
  27. while(br.ready()){
  28. String sb = br.readLine();
  29. System.out.println(sb);
  30. }
  31. }
  32. }
 
基于TCP的socket通信的Demo:
    服务端:
  1. package com.wangdaye.socketIO;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. /**
  9. * 基于TCP通信的socket服务器端
  10. * @author wangdaye
  11. *
  12. */
  13. publicclassTCPServer{
  14. publicstaticvoid main(String[] args){
  15. try{
  16. //1.创建服务器端socket,即serverSocket,指定绑定端口,并监听此端口。
  17. ServerSocket serverSocket =newServerSocket(8888);
  18. System.out.println("*************服务器即将启动,等待客户端链接*******************");
  19. //2.调用accept()方法开始监听,等待客户端连接,此时处于阻塞状态。
  20. Socket socket = serverSocket.accept();
  21. //3.获取输入流,读取客户端信息
  22. InputStream inputStream = socket.getInputStream();
  23. InputStreamReader reader =newInputStreamReader(inputStream);
  24. BufferedReader br =newBufferedReader(reader);
  25. String sb =null;
  26. while((sb = br.readLine())!=null){
  27. System.out.println("客户端说:"+ sb);
  28. }
  29. socket.shutdownInput();//关闭输入流
  30. //4.关闭资源
  31. br.close();
  32. reader.close();
  33. inputStream.close();
  34. socket.close();
  35. serverSocket.close();
  36. }catch(IOException e){
  37. // TODO Auto-generated catch block
  38. e.printStackTrace();
  39. }
  40. }
  41. }
    客户端:
  1. package com.wangdaye.socketIO;
  2. import java.io.IOException;
  3. import java.io.OutputStream;
  4. import java.io.PrintWriter;
  5. import java.net.Socket;
  6. import java.net.UnknownHostException;
  7. /**
  8. * 基于TCP通信的socket客户端
  9. * @author wangdaye
  10. *
  11. */
  12. publicclassTCPClient{
  13. publicstaticvoid main(String[] args){
  14. try{
  15. //1.创建客户端socket,并指定服务器地址和端口
  16. Socket socket =newSocket("localhost",8888);
  17. //2.获取输出流,向服务器端发送信息
  18. OutputStream outputStream = socket.getOutputStream();//字节输出流
  19. PrintWriter pw =newPrintWriter(outputStream);//将输出流打包成打印流
  20. pw.write("用户名:sb,密码:123");
  21. pw.flush();
  22. socket.shutdownOutput();
  23. //3.关闭资源
  24. outputStream.close();
  25. socket.close();
  26. }catch(UnknownHostException e){
  27. e.printStackTrace();
  28. }catch(IOException e){
  29. e.printStackTrace();
  30. }
  31. }
  32. }
多线程服务端:
  1. package com.wangdaye.socketIO;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. publicclassTCPThreadServer{
  5. publicstaticvoid main(String[] args)throwsException{
  6. ServerSocket serverSocket =newServerSocket(8888);
  7. System.out.println("***********************服务器启动成功,正在等待客户端连接*********************");
  8. Socket socket =null;
  9. int count =0;
  10. while(true){
  11. socket = serverSocket.accept();
  12. count++;
  13. System.out.println("当前客户端连接数量:"+ count);
  14. System.out.println("当前客户端IP地址是:"+ socket.getInetAddress()+",主机名:"+socket.getInetAddress().getHostAddress()+":"+ socket.getPort());
  15. ServerThread serverThread =newServerThread(socket);
  16. serverThread.run();
  17. }
  18. }
  19. }
基于UDP的Socket通信的Demo:
服务端:
  1. package com.wangdaye.socketIO.udp;
  2. import java.net.DatagramPacket;
  3. import java.net.DatagramSocket;
  4. import java.net.InetAddress;
  5. publicclassServerUdp{
  6. publicstaticvoid main(String[] args)throwsException{
  7. System.out.println("***************服务端已经启动,正在等待客户端发送数据*************");
  8. //接收客户端发送的数据
  9. //1.创建服务器端DatagramSocket,指定端口号
  10. DatagramSocket datagramSocket =newDatagramSocket(8800);
  11. //2.创建数据报,接收客户端发送的数据,指定数据包大小
  12. byte[] b =newbyte[1024];
  13. DatagramPacket datagramPacket =newDatagramPacket(b,b.length);
  14. //3.接收客户端发送的数据
  15. datagramSocket.receive(datagramPacket);//此方法在接收到数据之前会一直阻塞
  16. //4.查看客户端发送的信息,读取数据
  17. String str =newString(b,0, datagramPacket.getLength());
  18. System.out.println("我是服务器,客户端说:"+ str);
  19. //向客户端响应数据
  20. //1.获取客户端地址和端口
  21. InetAddress clientAddress=datagramPacket.getAddress();
  22. int clientPort = datagramPacket.getPort();
  23. String sb ="欢迎你,客户端";
  24. byte[] bytes = sb.getBytes();
  25. //2.创建要向客户端发送的数据
  26. DatagramPacket dp =newDatagramPacket(bytes,bytes.length,clientAddress,clientPort);
  27. //3.响应客户端
  28. datagramSocket.send(dp);
  29. //4.关闭连接
  30. datagramSocket.close();
  31. }
  32. }
 
客户端:
  1. package com.wangdaye.socketIO.udp;
  2. import java.net.DatagramPacket;
  3. import java.net.DatagramSocket;
  4. import java.net.InetAddress;
  5. publicclassClientUdp{
  6. publicstaticvoid main(String[] args)throwsException{
  7. //向服务器端发送数据
  8. //1.定义服务器的地址、端口号
  9. InetAddress inetAddress =InetAddress.getByName("localhost");
  10. int port =8800;
  11. String msg ="我是客户端,我了个去~";
  12. byte[] bytes = msg.getBytes();
  13. //2.创建数据报,包含发送的消息
  14. DatagramPacket packet =newDatagramPacket(bytes,bytes.length,inetAddress,port);
  15. //3.创建DatagramSocket对象
  16. DatagramSocket socket =newDatagramSocket();
  17. //4.发送数据
  18. socket.send(packet);
  19. //接收服务端响应数据
  20. //1.创建数据包,接收服务端响应数据
  21. byte[] receivedBytes =newbyte[1024];
  22. DatagramPacket dp =newDatagramPacket(receivedBytes,receivedBytes.length);
  23. //2.接收服务器端响应数据
  24. socket.receive(dp);
  25. //3.读取数据
  26. String reply =newString(receivedBytes,0,receivedBytes.length);
  27. System.out.println(reply);
  28. //4.关闭资源
  29. socket.close();
  30. }
  31. }
 
 
注意:
    1.生产环境下,对线程的优先级做一个控制,否则会效率低下
    2.输入输出流的关闭问题,关闭了socket,流也就关闭了
    3.传递对象,平时都是以字符串传递的
    4.传递文件
 





原文地址:https://www.cnblogs.com/douJiangYouTiao888/p/6473902.html