Java 网络编程

来源:互联网 发布:台式电脑网络连接不上 编辑:程序博客网 时间:2024/04/29 21:40

1.1、TCP,同步版本的Server:

package com.socket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;/** * TCP的网络编程,服务器 * @author Feng * */public class TCPTestServer{public static void main(String[] args) throws IOException, InterruptedException{//服务器开始监听6666号端口//从启动上说,必须要先启动服务器端程序ServerSocket ss = new ServerSocket(6666);//因为服务器需要不断等待连接,所以死循环等待while(true){System.out.println("等待连接申请中···");//接受链接申请,这样写只接受一个连接,这个方法是阻塞式的,如果没有任何连接申请就会一直等待Socket s = ss.accept();if(s.isConnected()){System.out.println("OK!!!!!");//使用输入流接受客户端传入的信息InputStream stream = s.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(stream));//注意,像这种输入流的方式属于同步输入,连接成功后如果客户端不传送东西,这里的输入流会一直等待,导致其他连接申请被搁置System.out.println(reader.readLine());}else{System.out.println("NO!!");}}}}

1.2、TCP,同步版本的Client:

package com.socket;import java.io.BufferedWriter;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.Socket;import java.net.UnknownHostException;/** * TCP网络编程,客户端 * @author Feng * */public class TCPTestClient {public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException{//客户端申请连接到 127.0.0.1:6666//客户端会给这边的socket随机分配端口号,具体是多少并不重要Socket s = new Socket("127.0.0.1", 6666);//连接成功之后,可以通过管道来进行通话,使用输出管道//这里的等待模拟:线连接,但是迟迟不发送信息,这个时候这个链接会被该客户端独占Thread.sleep(10000);OutputStream stream = s.getOutputStream();BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream));writer.write("SHTI!!!!你妹!!!!!");writer.flush();writer.close();s.close();}}


2、TCP,多线程的图片接收服务器

package com.socket;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class TCPJpgGetter {public static void main(String[] args) throws IOException{ServerSocket ss = new ServerSocket(6666);while(true){Socket s = ss.accept();new Thread(new Getter(s)).start();}}}/** * 多线程的图片接收类 * 服务器端开启多个线程用于接收传送过来的图片 */class Getter implements Runnable{private Socket s = null;public Getter(Socket s){this.s = s;}@Overridepublic void run() {try {String info = s.getInetAddress().toString();//从socket读取数据的输入流InputStream getter = s.getInputStream();//回传数据的输出流OutputStream sender = s.getOutputStream();//为了避免文件名重复的覆盖,使用编号int count = 1;File temp = new File("D:/" + info + "(" + count + ").jpg");while(temp.exists()){//这里的处理不是很严谨,还是有可能会导致文件覆盖temp = new File("D:/" + info + "(" + (++count) + ").jpg");}System.out.println("接收到来自:" + info + "的传送请求,存储名为:" + temp.getName());//创建文件并写入到磁盘的输出流FileOutputStream fileWriter = new FileOutputStream(temp);byte[] buf = new byte[1024];int len;while((len=getter.read(buf)) != -1){//写文件的时候要注意写的长度fileWriter.write(buf, 0, len);}sender.write("上传成功".getBytes("UTF-8"));fileWriter.close();s.close();} catch (IOException e) {e.printStackTrace();}}}



3.1、UDP,同步版本的“Server”:

package com.socket;import java.io.ByteArrayInputStream;import java.io.DataInputStream;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;/** * UDP的“服务器”,事实上UDP并没有明确地服务器和客户端的分类,因为是不安全连接,要做的就是确定目标IP和端口号,然后直接发送就好了 * @author Feng * */public class UDPTestServer {public static void main(String[] args) throws IOException{byte buf[] = new byte[1024];//DatagramPacket用来存放需要发送或者要接收的数据DatagramPacket dp = new DatagramPacket(buf, buf.length);//DatagramSocket就是UDP方式的socket,为服务器指定端口号6666DatagramSocket ds = new DatagramSocket(6666);while(true){//receive方法是阻塞式方法,等待接收数据ds.receive(dp);//获取发送源的IP地址和端口号,在发送端由于没有指定端口号,这里看到的端口是系统随机分配的端口System.out.println("收取到来自 " + dp.getAddress() + ":" + dp.getPort() + " 的信息:");//以字符串的形式获取数据并打印System.out.println("字符串:" + new String(buf, 0, dp.getLength()));//接受传送过来的信息,信息已经存储在buf之中ByteArrayInputStream in = new ByteArrayInputStream(buf);DataInputStream din = new DataInputStream(in);System.out.println("数字:" + din.readLong());System.out.println(); }}}


3.2、UDP,同步版本的“Client”:

package com.socket;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;public class UDPTestClient {public static void main(String[] args) throws IOException{byte[] buf = new String("你好!~~").getBytes();//将一个long类型数据转换成byte[];long num = 123412341234L;ByteArrayOutputStream out = new ByteArrayOutputStream();DataOutputStream dout = new DataOutputStream(out);dout.writeLong(num);byte[] buf2 = out.toByteArray();System.out.println(buf2.length);//新建socket的时候如果不指定端口号,那系统将为其默认指定一个地址,作为发送方,这个socket不需要指定端口DatagramSocket ds = new DatagramSocket();DatagramPacket dp = null;//DatagramPacket是UDP模式下传输信息的媒介//指定目的地址为127.0.0.1:6666dp = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 6666));ds.send(dp);dp = new DatagramPacket(buf2, buf2.length, new InetSocketAddress("127.0.0.1", 6666));ds.send(dp);ds.close();}}


4、UDP聊天小程序

package com.socket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.SocketException;import java.net.UnknownHostException;/** * 两个线程,定义一个接受和一个发送端 * 写入目标机器的IP地址和端口号即可通信 * 中文问题:我的MyEclipse默认编码是UTF-8,运行的时候要在Run-Run Configuration-Common-指定GBK,否则会出现中文乱码问题 * @author Feng */public class UDPTalker {public static void main(String[] args) throws IOException{InetAddress myAdd = InetAddress.getLocalHost();System.out.println("本机地址:" + myAdd);BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入目标机器IP地址:");String ipAdd = reader.readLine();System.out.println("请输入目标机器端口号:");int port = Integer.parseInt(reader.readLine());DatagramSocket sender = new DatagramSocket();DatagramSocket listener = new DatagramSocket(6666);//消息发送目的地InetSocketAddress address = new InetSocketAddress(ipAdd, port);new Thread(new Send(sender, address)).start();new Thread(new Listen(listener)).start();}}/** * 发送线程,接受键盘输入,并将消息发往指定的地址 * @author Feng * */class Send implements Runnable{private DatagramSocket ds = null;private InetSocketAddress address = null;public Send(DatagramSocket ds, InetSocketAddress address){this.ds = ds;this.address = address;}@Overridepublic void run() {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String line = null;try {while((line=reader.readLine()) != null){byte[] temp = line.getBytes("UTF-8");//发送数据包,指定了发送的内容以及目的地DatagramPacket dp = new DatagramPacket(temp, temp.length, address);ds.send(dp);if("exit".equals(line)){break;}}} catch (IOException e) {e.printStackTrace();}}}/** * 接收线程,等待接收消息并显示 * @author Feng * */class Listen implements Runnable{private DatagramSocket ds = null;public Listen(DatagramSocket ds){this.ds = ds;}@Overridepublic void run() {try {while(true){byte[] temp = new byte[1024];//接收数据包,缓存大小为1KDatagramPacket dp = new DatagramPacket(temp, temp.length);ds.receive(dp);String address = dp.getAddress().getHostAddress() + "-" + dp.getPort();String data = new String(dp.getData(), 0, dp.getLength(), "UTF-8");System.out.println(address + ": " + data);}} catch (IOException e) {e.printStackTrace();}}}