网络编程——1对1,单次通信

实现通信,我们使用基于TCP协议的java.net.Socket和java.net.ServerSocket,先来创建一个服务器端和客户端。

为了保证服务器和客户端之间可以进行通信,他们必须使用相同的端口,我先给出一个接口,该接口定义了默认端口号:

package gw.about_net.core;

public interface INet {
	int DEFAULT_PORT = 54187;
}
1.服务器

创建服务器连接步骤:
1) 先创建一个ServerSocket对象,在其构造方法中指定需要监听的端口(负责在操作系统中把当前进程注册为服务器进程)
2)使用accept()方法侦听来自客户端的连接请求
3)创建通信信道
4)使用readUTF()方法侦听客户端发送的消息
5)关闭通信信道和服务器

先给出服务器的代码:

package gw.about_net.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import gw.about_net.core.INet;

public class SimpleServer {
	private ServerSocket server;
	private int port;		//服务器必须设置一个端口号,保证客户端能找到服务器
	DataInputStream dis;	//输入通信信道
	DataOutputStream dos;	//输出通信信道
	
	public SimpleServer() {
		this.port = INet.DEFAULT_PORT;
	}
	
	//如若将set方法的类型改为本类类型,则要设置返回值为“return this;”
	public SimpleServer setPort(int port){
		this.port = port;
		return this;
	}
	
	public void startup() {
		try {
			System.out.println("开始建立服务器......");
			server = new ServerSocket(port);
			System.out.println("服务器建立成功!");
			System.out.println("开始侦听客户端连接请求.......");
			Socket client = server.accept();	
			//该方法一直监听端口,等待客户的连接请求,如果接收到一个连接请求,accept()方法就会返回一个Socket 对象,这个Socket对象与客户端的Socket对象形成了一条通信线路;该方法会使服务器处于阻塞状态,等待用户请求。

			
			String clientIp = client.getInetAddress().getHostAddress();//获取请求连接的客户端的IP地址
			System.out.println("侦听到来自["+clientIp+"]的连接请求,并连接成功");
			
			System.out.println("开始建立与客户端通信信道.......");
			 dis = new DataInputStream(client.getInputStream());
			 dos = new DataOutputStream(client.getOutputStream());
			 System.out.println("建立成功!!!");
			
			System.out.println("开始侦听客户端发送的消息......");
			String message = dis.readUTF();		//此处,若接收不到消息,不继续执行下一步
			System.out.println("来自星星的消息:["+message+"]");
			dos.writeUTF("["+message+"]");		//将接收到的消息直接返回
			
			close();			//此处调用关闭函数
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	//关闭通信信道,关闭服务器
	private void close() {
		try {
			dis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			dos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


给出一个测试类:

package gw.abour_net.test;

import gw.about_net.server.SingleClientServer;

public class ServerTest {

	public static void main(String[] args) {
		new SimpleServer().startup();//

	}

}
运行结果:

在这里插入图片描述
看运行结果,只运行了一半,并且箭头所指位置说明还处于运行中,即上述代码中accept()方法处,这是因为没有客户端,accept()方法如果不接收客户端发来的连接消息,就不会再运行下去。

2.客户端

客户端连接步骤:
1)创建一个Socket对象,在其构造方法中给出主机和端口号,用于连接服务器
2)创建通信信道
3)开始进行通信
4)发送消息

每当客户程序创建一个Socket对象,操作系统就会为客户随机分配一个端口。

客户端代码:

package gw.about_net.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import gw.about_net.core.INet;


public class SimpleClient {
	public static final String DEFAULT_IP = "127.0.0.1";
	
	private Socket socket;
	//通过服务器端IP和端口号确定是哪个服务器
	private String serverIp;
	private int serverPort;
	
	private DataInputStream dis;
	private DataOutputStream dos;
	
	public SimpleClient() {
		serverIp= DEFAULT_IP;
		serverPort = INet.DEFAULT_PORT;
	}
	
	public SimpleClient setServerIp(String serverIp) {
		this.serverIp = serverIp;
		return this;
	}
	
	public SimpleClient setServerPort(int serverPort) {
		this.serverPort = serverPort;
		return this;
	}
	
	public void connectToServer() {
		try {
			System.out.println("开始连接服务器.......");
			socket = new Socket(serverIp, serverPort);	//该语句会响应accept()
			System.out.println("已连接并开始创建通信信道......");
			dis = new DataInputStream(socket.getInputStream());
			dos = new DataOutputStream(socket.getOutputStream());
			System.out.println("通信信道创建完毕,开始发送消息:");
			dos.writeUTF("你好!");
			String message = dis.readUTF();
			System.out.println("来自太阳的消息:"+message);
			close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	private void close() {
		try {
			dis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			dos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

测试类:
客户端:

package gw.abour_net.test;

import gw.about_net.client.SimpleClient;

public class ClientTest {

	public static void main(String[] args) {
		SimpleClient client = new SimpleClient();
		client.connectToServer();
	}
}

服务器:

public class ServerTest {

	public static void main(String[] args) {
		new SimpleServer().startup();
	}

}

运行结果:

服务器端:
在这里插入图片描述
客户端:
在这里插入图片描述
至此,已经实现了服务器端与客户端的简单连接和消息互通。
下一篇:《网络通信——1对1,多次通信》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值