JAVA Socket基础例程

1、tcp通信

例程:由客户端发一条字符串到服务端,服务端收到之后相应,客户端收取相应字符串。

首先是服务端接受连接的代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;



public class Test {
	public static void main(String[] args) throws IOException, InterruptedException {
		//创建一个服务端socket,指定绑定端口
		ServerSocket serverSocket = new ServerSocket(8888);
		//开始监听端口,等待客户端的连接
		System.out.println("服务器已经启动,进入阻塞状态,等待客户端连接");
		Socket socket = serverSocket.accept();
		System.out.println("收到客户端连接,客户端ip为:"+socket.getRemoteSocketAddress());
		//获取一个输入流,读取信息
		InputStream is = socket.getInputStream();//字节输入流
		InputStreamReader reader = new InputStreamReader(is);//将字节输入流转换为字符流,如果要接收对象,就改成ObjectInputStream
		BufferedReader br = new BufferedReader(reader);//为字符流添加缓冲
		
		String receive = null;
		while((receive=br.readLine())!=null){
			System.out.println("收到客户端信息:"+receive);
		}
		socket.shutdownInput();//关闭输入流
		
		//获取输出流,相应客户端的请求
		Thread.sleep(5000);//延迟响应
		OutputStream os = socket.getOutputStream();
		PrintWriter out = new PrintWriter(os);//如果要发哦是哪个对象,就把这里改为ObjectOutputStream
		out.write("欢迎你客户端!");
		out.flush();//本句必须执行
		
		//关闭资源
		out.close();
		br.close();
		reader.close();
		is.close();
		socket.close();
		serverSocket.close();
	}
}

然后是客户端发送请求连接的代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;


public class TestClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		// TODO Auto-generated method stub
		//1、创建一个socket,指定服务器地址和端口号
		System.out.println("正在试图向服务器端建立连接");
		Socket socket = new Socket("192.168.1.147",8888);
		System.out.println("连接建立成功,准备发送消息");
		//2、获取输出流向服务端发送信息
		OutputStream outputStream = socket.getOutputStream();
		PrintWriter printWriter = new PrintWriter(outputStream);//将输出流包装成打印流,如果要传输对象,就把这里改为ObjectOutputStream
		printWriter.print("服务器你好");//可以调用ObjectOutputStream的writeObject方法
		printWriter.flush();//本句必须执行
		System.out.println("信息发送成功!!等待服务器相应");
		//关闭输出流
		socket.shutdownOutput();
		
		//3、获取输入流,接收服务器的相应
		System.out.println("服务器正在响应,服务器ip"+socket.getRemoteSocketAddress());
		InputStream is = socket.getInputStream();
		InputStreamReader reader = new InputStreamReader(is);
		BufferedReader buffer = new BufferedReader(reader);//包装为字符流
		String response = null;
		while((response = buffer.readLine())!=null){
			System.out.println("收到服务器响应内容:"+response);
		}
		
		//关闭相关资源
		buffer.close();
		is.close();
		
		printWriter.close();
		socket.close();
		
		
	}

}

在上例中服务器一次只能接收一个客户端发来的请求,并且响应完毕后程序即结束,如果要使服务器可以相应多个客户端的请求,就需要用到子线程,下面把服务端的代码挪到一个子线程中去

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;


public class ServerThread extends Thread {
	public Socket socket;
	public ServerThread(){}
	public ServerThread(Socket socket){
		this.socket = socket;
	}
	public void run(){
		//获取一个输入流,读取信息
		InputStream is = null;//字节输入流
		InputStreamReader reader = null;//将字节输入流转换为字符流
		BufferedReader br = null;
		PrintWriter out = null;
		try {
				 is = socket.getInputStream();//字节输入流
				 reader = new InputStreamReader(is);//将字节输入流转换为字符流
				 br = new BufferedReader(reader);//为字符流添加缓冲
				
				String receive = null;
				
					while((receive=br.readLine())!=null){
						System.out.println("收到客户端信息:"+receive);
					}
					socket.shutdownInput();//关闭输入流
					
					//获取输出流,相应客户端的请求
					Thread.sleep(5000);//延迟相应
					OutputStream os = socket.getOutputStream();
					out = new PrintWriter(os);
					out.write("欢迎你客户端!");
					out.flush();//本句必须执行
					
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					//关闭资源
					try {
						if(out!=null)out.close();
						if(br!=null)br.close();
						if(reader!=null)reader.close();
						if(is!=null)is.close();
						if(socket!=null)socket.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
	}
}
调用方法:

public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		ServerSocket serverSocket = new ServerSocket(8888);
		int count=0;//记录客户端的数量
		Socket socket=null;
		System.out.println("服务器已经启动,进入阻塞状态,等待客户端连接");
		//循环监听,等待客户端的连接
		while(true){
			socket = serverSocket.accept();//此处进行阻塞
			//如果收到客户端请求,就创建一个新的线程
			System.out.println("收到客户端连接,客户端ip为:"+socket.getInetAddress().getHostAddress());
			ServerThread serverThread = new ServerThread(socket);
			serverThread.setPriority(4);//设置线程优先级,防止服务器卡掉
			//启动线程
			serverThread.start();
			count++;
		}
	}

2、UDP通信,与tcp相同,不过使用的socket类为DatagramSocket,而且发的不是字节流,而是报文

服务端例程

public static void main(String[] args) throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		//创建服务器端DatagramSocket,指定端口
		DatagramSocket socket = new DatagramSocket(8800);
		//创建数据报,用于接收客户端发的数据
		byte[] data = new byte[1024];
		DatagramPacket clientPacket = new DatagramPacket(data, data.length);//接收用两个参数的构造,发送用四个
		//3、接收客户端发送的数据,保存在数据报中
		System.out.println("udp接收端已经启动,正在等待数据");
		socket.receive(clientPacket);//此方法在接收到数据报之前会一直阻塞
		//4、读取数据报,其实就是data字节数组
		String info = new String(data,0,clientPacket.getLength());//第二个参数是偏移,第三个参数是长度
		System.out.println("客户端发来:"+info);
		
		/**
		 * 向客户端相应数据
		 */
		Thread.sleep(2000);
		//1、定义客户端的地址、端口号、数据
		InetAddress clientAddress = clientPacket.getAddress();//这里的packet就是socket收到的packet,里面全是客户机的信息
		byte[] data2 = "欢迎udp客户端!!".getBytes();
		//2、创建数据报,包含响应的数据信息
		DatagramPacket serverPacket = new DatagramPacket(data2, data2.length, clientAddress,clientPacket.getPort());//发送数据报用4个参数的构造函数
		//3、发送数据报
		socket.send(serverPacket);//DatagramSocket只记录自己的端口和地址,对于要发出的,根据传入的packet来确定
		
	}

客户端例程

public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		//1、定义服务器的地址,端口号、数据
		InetAddress inetAddress = InetAddress.getByName("192.168.1.147");//给出目标主机的InetAddress
		int port = 8800;
		byte[] data = "你好我是UDP请求".getBytes();
		//2、创建数据报,包含发送的数据信息
		DatagramPacket packet = new DatagramPacket(data, data.length, inetAddress, port);//发送数据用4个参数的构造函数
		//3、创建datagramSocket对象
		DatagramSocket socket = new DatagramSocket();
		//4、发送数据报
		socket.send(packet);
		System.out.println("udp发送成功");
		
		/**
		 * 接受服务端响应的数据
		 */
		//1、创建数据报
		byte[] data2 = new byte[1024];
		DatagramPacket serverPacket = new DatagramPacket(data2, data2.length);
		//2、接收响应的数据
		socket.receive(serverPacket);
		//3、读取数据
		String reply = new String(data2,0,serverPacket.getLength());
		System.out.println("服务器响应内容:"+reply);
	}

3、使用socket发送小文件文件

客户端例程

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;


public class TestClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		// TODO Auto-generated method stub
		//1、创建一个socket,指定服务器地址和端口号
		System.out.println("正在试图向服务器端建立连接");
		Socket socket = new Socket("192.168.1.147",8888);
		System.out.println("连接建立成功,准备发送消息");
		//2、获取输出流向服务端发送信息
		OutputStream outputStream = socket.getOutputStream();
		FileInputStream fileInputStream = new FileInputStream(new File("E:/xh.jpg"));
		BufferedInputStream bis = new BufferedInputStream(fileInputStream);
		byte[] bytes = new byte[fileInputStream.available()];//把整个文件都放到内存里去,注意文件不要过大
		bis.read(bytes);
		outputStream.write(bytes);
		if(fileInputStream!=null){
			fileInputStream.close();
		}
		//关闭输出流
		socket.shutdownOutput();
		
		//3、获取输入流,接收服务器的相应
		System.out.println("服务器正在响应,服务器ip"+socket.getRemoteSocketAddress());
		InputStream is = socket.getInputStream();
		InputStreamReader reader = new InputStreamReader(is);
		BufferedReader buffer = new BufferedReader(reader);//包装为字符流
		String response = null;
		while((response = buffer.readLine())!=null){
			System.out.println("收到服务器响应内容:"+response);
		}
		
		
		
		
		//关闭相关资源
		buffer.close();
		is.close();
		socket.close();
		
		
	}

}

服务端例程

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;



public class Test {
	public static void main(String[] args) throws IOException, InterruptedException {
		//创建一个服务端socket,指定绑定端口
		ServerSocket serverSocket = new ServerSocket(8888);
		//开始监听端口,等待客户端的连接
		System.out.println("服务器已经启动,进入阻塞状态,等待客户端连接");
		Socket socket = serverSocket.accept();
		System.out.println("收到客户端连接,客户端ip为:"+socket.getRemoteSocketAddress());
		//获取一个输入流,读取信息
		InputStream is = socket.getInputStream();//字节输入流
		BufferedInputStream clientInputStream = null;
		//生成一个临时文件
		File file = new File("e:/xh.jpg");
		clientInputStream = new BufferedInputStream(socket.getInputStream());
		file.createNewFile();
		BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(file));//对输出流进行缓存控制
		byte[] buf = new byte[1024*256];//每次写入256k
		int len;
		while((len = clientInputStream.read(buf))!=-1){
			fos.write(buf,0,len);
			fos.flush();
			System.out.println("写入字节流成功"+len);
		}
		socket.shutdownInput();//关闭输入流
		
		//获取输出流,相应客户端的请求
		
		OutputStream os = socket.getOutputStream();
		PrintWriter out = new PrintWriter(os);//如果要发个对象,就把这里改为ObjectOutputStream
		out.write("文件写入成功!");
		out.flush();//本句必须执行
		socket.shutdownOutput();
		
		//关闭资源
		out.close();
		is.close();
		socket.close();
		serverSocket.close();
	}
}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值