【JAVA网络流之TCP与UDP 】
一、ServerSocket
java.lang.Object
|-java.net.ServerSocket
有子类SSLServerSocket。
此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。 |
常用构造方法:
ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 |
常用方法:
|
|
|
|
|
|
|
|
|
|
二、Socket
Java.lang.Object
|-java.net.Socket
常用构造方法:
|
Socket(InetAddress address, int port) |
|
常用方法:
void |
bind(SocketAddress bindpoint) |
void |
close() |
void |
connect(SocketAddress endpoint) |
void |
connect(SocketAddress endpoint, int timeout) |
getInetAddress()
|
|
getInputStream()
|
|
getOutputStream()
|
|
int |
getPort()
|
void |
shutdownInput()
|
void |
shutdownOutput()
|
三、DatagramSocket
Java.lang.Object
|-java.net.DatagramSocket
常用构造方法:
|
DatagramSocket(int port) |
|
DatagramSocket(int port, InetAddress laddr) |
常用方法:
应当注意的是,该类既能发送数据包也能接受数据包
void |
bind(SocketAddress addr) |
void |
close() |
void |
connect(InetAddress address, int port) |
void |
connect(SocketAddress addr) |
getInetAddress()
|
|
void |
receive(DatagramPacket p) |
void |
send(DatagramPacket p) |
四、DatagramPacket
Java.lang.Object
|-java.net.DatagramPacket
常用构造方法:
构造方法摘要 |
|
DatagramPacket(byte[] buf, int length) |
|
DatagramPacket(byte[] buf, int length, InetAddress address, int port) |
|
DatagramPacket(byte[] buf, int length, SocketAddress address) |
常用方法:
getAddress() |
|
int |
getPort()
|
void |
setAddress(InetAddress iaddr) |
void |
setData(byte[] buf, int offset, int length) |
void |
setPort(int iport)
|
void |
setSocketAddress(SocketAddress address) |
五、简单TCP应用实例1:服务端小写转大写服务
服务端程序:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStreamReader; 4 import java.io.PrintWriter; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 8 /** 9 * 这是服务端程序 10 * @author kuangdaoyizhimei 11 * 12 */ 13 public class Server 14 { 15 public static void main(String args[]) throws IOException 16 { 17 ServerSocket ss=new ServerSocket(7894); 18 Socket s=ss.accept(); 19 System.out.println(s.getInetAddress().getHostAddress()+"已连接。"); 20 BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream())); 21 PrintWriter pw=new PrintWriter(s.getOutputStream(),true); 22 String str=null; 23 while((str=br.readLine())!=null) 24 { 25 System.out.println(str); 26 pw.println(str.toUpperCase());//注意println方法的使用在这里是必须的,否则会产生死锁 27 } 28 s.close(); 29 ss.close(); 30 } 31 }
客户端程序:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStreamReader; 4 import java.io.PrintWriter; 5 import java.net.Socket; 6 import java.net.UnknownHostException; 7 8 /** 9 * 这是客户端程序。 10 * @author kuangdaoyizhimei 11 * 12 */ 13 public class Client 14 { 15 public static void main(String args[]) throws UnknownHostException, IOException 16 { 17 Socket s=new Socket("192.168.1.101",7894); 18 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 19 BufferedReader bin=new BufferedReader(new InputStreamReader(s.getInputStream())); 20 PrintWriter pw=new PrintWriter(s.getOutputStream(),true); 21 String str=null; 22 while((str=br.readLine())!=null) 23 { 24 pw.println(str); 25 String result=bin.readLine(); 26 System.out.println(result);//注意println方法的使用在这里是必须的,否则会产生死锁 27 } 28 s.close(); 29 } 30 }
运行结果:
服务端运行结果:
客户端运行结果:
二、简单UDP服务演示:局域网群聊小程序。
程序使用的广播地址是192.168.1.255,每个客户端的接收端口是6544。
程序中使用了多线程技术。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package p01.UDPTransferDemo.p01.UDPTransferDemo; 2 import java.io.IOException; 3 import java.net.DatagramPacket; 4 import java.net.DatagramSocket; 5 import java.net.InetAddress; 6 import java.io.BufferedReader; 7 import java.io.InputStreamReader; 8 /** 9 * 接收线程ReceiveThread 10 * @author kuangdaoyizhimei 11 */ 12 class ReceiveThread implements Runnable 13 { 14 DatagramSocket ds=null; 15 public ReceiveThread(DatagramSocket ds) 16 { 17 this.ds=ds; 18 } 19 @Override 20 public void run() 21 { 22 while(true) 23 { 24 try 25 { 26 byte buf[]=new byte[1024]; 27 //2.创建接收数据报 28 DatagramPacket dp=new DatagramPacket(buf, buf.length); 29 ds.receive(dp); 30 //3.显示数据报信息 31 System.out.println(dp.getAddress().getHostAddress()+":"+dp.getPort()+":"+new String(dp.getData(),0,dp.getLength())); 32 } 33 catch(IOException e) 34 { 35 System.out.println("接受线程产生异常!"); 36 } 37 } 38 } 39 } 40 /** 41 * 发送线程SendThread 42 * @author kuangdaoyizhimei 43 * 44 */ 45 class SendThread implements Runnable 46 { 47 DatagramSocket ds=null; 48 public SendThread(DatagramSocket ds) 49 { 50 this.ds=ds; 51 } 52 @Override 53 public void run() 54 { 55 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 56 String str=null; 57 try { 58 while((str=br.readLine())!=null) 59 { 60 try 61 { 62 //2.创建发送数据包。 63 DatagramPacket dp=new DatagramPacket(str.getBytes(),str.getBytes().length,InetAddress.getByName("192.168.1.255"),6544); 64 //3.发送数据包 65 ds.send(dp); 66 } 67 catch(IOException e) 68 { 69 System.out.println("发送线程产生异常!"); 70 } 71 } 72 } 73 catch (IOException e) { 74 e.printStackTrace(); 75 } 76 } 77 } 78 /** 79 * 主类UDPTransferDemo 80 * @author kuangdaoyizhimei 81 * 82 */ 83 public class UDPTransferDemo { 84 public static void main(String args[]) throws IOException 85 { 86 DatagramSocket Send=new DatagramSocket(); 87 DatagramSocket Receive=new DatagramSocket(6544); 88 new Thread(new ReceiveThread(Receive)).start(); 89 new Thread(new SendThread(Send)).start(); 90 } 91 }
运行结果:
三、TCP应用之文本文件上传
在和源文件同一个文件夹中预先准备一个文本文件aim.txt,里面内容自定义。
服务端程序:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package p04.TCPUpperLoadFileDemo.p01.TCPUpperLoadTextFileDemo; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.File; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.io.InputStreamReader; 10 import java.io.OutputStream; 11 import java.io.OutputStreamWriter; 12 import java.net.ServerSocket; 13 import java.net.Socket; 14 15 public class TCPUpperLoadServer { 16 public static void main(String args[]) throws IOException 17 { 18 ServerSocket ss=new ServerSocket(9876); 19 Socket s=ss.accept(); 20 InputStream is=s.getInputStream(); 21 BufferedReader brIn=new BufferedReader(new InputStreamReader(is)); 22 OutputStream os=s.getOutputStream(); 23 BufferedWriter bwOut=new BufferedWriter(new OutputStreamWriter(os)); 24 String str=null; 25 File file=new File("副本.txt"); 26 BufferedWriter bw=new BufferedWriter(new FileWriter(file)); 27 while((str=brIn.readLine())!=null) 28 { 29 System.out.println(str); 30 bw.write(str); 31 bw.newLine();//此处换行是为了写到文件的换行 32 bw.flush(); 33 } 34 bw.close(); 35 bwOut.write("上传成功!"); 36 bwOut.flush(); 37 s.close(); 38 } 39 }
客户端程序:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package p04.TCPUpperLoadFileDemo.p01.TCPUpperLoadTextFileDemo; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.File; 6 import java.io.FileReader; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.io.InputStreamReader; 10 import java.io.OutputStream; 11 import java.io.OutputStreamWriter; 12 import java.net.Socket; 13 import java.net.UnknownHostException; 14 15 public class TCPUpperLoadClient { 16 17 public static void main(String[] args) throws UnknownHostException, IOException 18 { 19 Socket socket=new Socket("192.168.209.1",9876); 20 InputStream is=socket.getInputStream(); 21 BufferedReader brIn=new BufferedReader(new InputStreamReader(is)); 22 OutputStream os=socket.getOutputStream(); 23 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os)); 24 File file=new File("aim.txt"); 25 FileReader fr=new FileReader(file); 26 BufferedReader br=new BufferedReader(fr); 27 String str=null; 28 while((str=br.readLine())!=null) 29 { 30 bw.write(str); 31 bw.newLine();//此处换行是为了给服务器端读取一行的结束标记。 32 bw.flush(); 33 } 34 socket.shutdownOutput();//没有这一句话两端将都处于等待状态。 35 br.close(); 36 str=brIn.readLine(); 37 System.out.println(str); 38 } 39 }
运行结果:
四、TCP应用之媒体文件上传。
准备:aim.mp4文件,放在和源代码文件同一个目录下
客户端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package p04.TCPUpperLoadFileDemo.p02.TCPUpperLoadMultipleFileDemo; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.InputStreamReader; 9 import java.io.OutputStream; 10 import java.net.Socket; 11 import java.net.UnknownHostException; 12 13 public class TCPUpperLoadMultipleFileClient { 14 15 public static void main(String[] args) throws UnknownHostException, IOException { 16 Socket socket=new Socket("192.168.209.1",9876); 17 InputStream is=socket.getInputStream(); 18 OutputStream os=socket.getOutputStream(); 19 byte buf[]=new byte[1024]; 20 File file=new File("aim.mp4"); 21 FileInputStream fis=new FileInputStream(file); 22 int length=0; 23 while((length=fis.read(buf))!=-1) 24 { 25 os.write(buf, 0, length); 26 os.flush(); 27 } 28 fis.close(); 29 socket.shutdownOutput(); 30 31 /** 32 * 显示上传状态信息 33 */ 34 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 35 String str=br.readLine(); 36 System.out.println(str); 37 socket.close(); 38 } 39 40 }
服务端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package p04.TCPUpperLoadFileDemo.p02.TCPUpperLoadMultipleFileDemo; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.net.ServerSocket; 9 import java.net.Socket; 10 11 public class TCPUpperLoadMultipleFileServer { 12 13 public static void main(String[] args) throws IOException { 14 ServerSocket ss=new ServerSocket(9876); 15 Socket socket=ss.accept(); 16 InputStream is=socket.getInputStream(); 17 OutputStream os=socket.getOutputStream(); 18 FileOutputStream fos=new FileOutputStream(new File("副本.mp4")); 19 byte buf[]=new byte[1024]; 20 int length=-1; 21 while((length=is.read(buf))!=-1) 22 { 23 fos.write(buf, 0, length); 24 fos.flush(); 25 } 26 fos.close(); 27 os.write("文件上传成功!".getBytes()); 28 socket.close(); 29 ss.close();//服务器一般不关闭,这里只是用于演示,所以关闭。 30 } 31 }
运行结果:
五、TCP应用之QQ群聊。
客户端之输入端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 此程序模拟QQ输入 3 */ 4 import java.io.BufferedReader; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.Socket; 10 import java.net.UnknownHostException; 11 12 public class TCPTransferQQImitateClient { 13 14 public static void main(String[] args) throws UnknownHostException, IOException { 15 System.out.println("这是用户信息输入窗口:"); 16 Socket socket=new Socket("192.168.209.1",8080); 17 OutputStream os=socket.getOutputStream(); 18 PrintWriter pw=new PrintWriter(os,true); 19 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 20 String str=null; 21 while((str=br.readLine())!=null) 22 { 23 if(str.equals("over")) 24 { 25 break; 26 } 27 pw.println(str); 28 } 29 br.close(); 30 pw.close(); 31 socket.shutdownOutput(); 32 socket.close(); 33 } 34 }
客户端之接收端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 /** 8 * 此程序模拟群聊输出 9 * @author kuangdaoyizhimei 10 * 11 */ 12 public class ReceiveInformationClient { 13 14 public static void main(String[] args) throws IOException { 15 System.out.println("这是群聊显示窗口:"); 16 ServerSocket ss=new ServerSocket(8000); 17 while(true) 18 { 19 Socket s=ss.accept(); 20 InputStream is=s.getInputStream(); 21 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 22 String str=null; 23 str=br.readLine(); 24 System.out.println(str); 25 } 26 } 27 }
服务端之用户接入端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 此程序模拟服务器处理用户接入 3 */ 4 import java.io.IOException; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 import java.util.HashSet; 8 import java.util.HashSet; 9 10 public class TransmitServer { 11 public static void main(String[] args) throws IOException { 12 System.out.println("这是服务器处理多线程窗口:"); 13 ServerSocket ss=new ServerSocket(8080); 14 HashSet<String>hs=new HashSet<String>(); 15 while(true) 16 { 17 Socket socket=ss.accept(); 18 System.out.println("用户"+socket.getInetAddress().getHostName()+"接入!"); 19 Thread thread=new Thread(new ClientHandle(socket,hs)); 20 thread.start(); 21 } 22 } 23 }
服务端之转发端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.Socket; 8 import java.util.HashSet; 9 /** 10 * 此程序模拟服务器处理单个用户的线程接入和数据转发。 11 * @author kuangdaoyizhimei 12 * 13 */ 14 public class ClientHandle implements Runnable { 15 private Socket socket; 16 private HashSet<String>list; 17 public ClientHandle(Socket socket, HashSet<String> list) { 18 this.socket=socket; 19 this.list=list; 20 } 21 22 @Override 23 public void run() { 24 System.out.println("这是服务器处理单线程窗口:(核心窗口)"); 25 try 26 { 27 list.add(socket.getInetAddress().getHostAddress()); 28 InputStream is=socket.getInputStream(); 29 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 30 String ip=socket.getInetAddress().getHostAddress(); 31 int port=socket.getPort(); 32 String str=ip+":"+port+" :"; 33 String temp=null; 34 while((temp=br.readLine())!=null) 35 { 36 for(String s:list) 37 { 38 Socket sk=new Socket(s,8000); 39 OutputStream osm=sk.getOutputStream(); 40 PrintWriter pw=new PrintWriter(osm,true); 41 pw.println(str+temp); 42 sk.close(); 43 } 44 } 45 } 46 catch(IOException e) 47 { 48 System.out.println("用户"+socket.getInetAddress().getHostAddress()+"退出!"); 49 } 50 } 51 }
运行结果: