实现通信,我们使用基于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,多次通信》