【练习】SOCKET
例1:建立发送端A和接收端B,B的监听端口为1111,A通过UDP协议发送消息到B,B打印A发送的消息。
接收端:
public class UdpReceiver { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(1111); byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); System.out.println(new String(dp.getData(), 0, dp.getLength())//只把buf中非空部分转化为字符串 + " from " + dp.getAddress() + ":" + dp.getPort()); ds.close(); } }
发送端:
public class UdpSender { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(); String msg = "嗨,你好"; byte[] buf = msg.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 1111); ds.send(dp); ds.close(); } }
例2:写一个基于TCP协议的客户端和服务端,客户端向服务端上传图片,服务端保存图片到本地并向客户端发送反馈信息,要求服务端实现1对多并行服务。
分析:服务端需要服务端一直处于监听状态,以满足随机访问,可用while循环实现;要实现并行服务,则要用到多线程,每个线程单独处理一个请求。
服务端:
class ServerThread implements Runnable { Socket s; public ServerThread(Socket s) { this.s = s; } @Override public void run() { try { InputStream is = s.getInputStream(); String fileName = "222-" + s.getPort(); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("E:\\" + fileName + ".jpg")); byte[] buf = new byte[1024]; int len = 0; while ((len = is.read(buf)) != -1) bos.write(buf, 0, len); OutputStream os = s.getOutputStream(); // 给客户端发送反馈信息 os.write(("to " + s.getPort() + ":收到了").getBytes()); // 强行关闭输出流,防止相互忙等造成死锁。 s.shutdownOutput(); os.close(); is.close(); bos.close(); s.close(); } catch (IOException e) { try { throw new IOException("连接错误"); } catch (IOException e1) { e1.printStackTrace(); } } } } public class TcpServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(1111); while (true) { // 一个线程处理一个请求 Thread t = new Thread(new ServerThread(ss.accept())); t.start(); } } }
客户端:
public class TcpClient { public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException { Socket s = new Socket("127.0.0.1", 1111); OutputStream os = s.getOutputStream(); BufferedInputStream bis = new BufferedInputStream(new FileInputStream( "E:\\2.jpg")); byte[] buf = new byte[1024]; for (int len; (len = bis.read(buf)) != -1;) os.write(buf, 0, len); // 强行关闭输出流,防止相互忙等造成死锁。 s.shutdownOutput(); InputStream is = s.getInputStream(); // 接受服务器的反馈信息 byte[] msg = new byte[1024]; StringBuilder sb = new StringBuilder(); for (int len; (len = is.read(msg)) != -1;) sb.append(new String(msg, 0, len)); System.out.println(sb.toString()); bis.close(); os.close(); s.close(); }
由于本实验是在本地进行,因此客户端目标IP是IPV4环回地址,并且多用户访问也只能通过连续运行客户端来模拟,利用随机的客户端端口来区分不同用户。