先写服务端,一定要先执行服务端
package wangluobiancheng;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
/*
* TCP通信严格区分客户端和服务器端,在通信时必须先由客户端去连接服务器端才能实现通信,服务器端不能主动连接客户端
* 并且服务器端程序要先启动,等待客户端的连接
* ServerSocket类,用于表示服务器端,通信时要先创建代表服务器端的ServerSocket对象,相当于开启一个服务,此服务会等待客户端的连接。
* Server类,表示客户端,创建Server对象,使用该对象向服务器端发出连接请求,服务器端响应后,客户端再次向服务器端发送确认信息,确认连接
* ServerSocket()使用该构造方法在创建ServerSocket对象时,并没有绑定端口号,这样的对象创建的服务器端没有监听任何端口,不能直接使用
* *最常用ServerSocket(int port)可以将其绑定到一个指定的端口号上(参数port就是端口号)。客户端需要指定的端口号来访问服务器端程序
* ServerSocket(int port,int backlog)可以将其绑定到一个指定的端口号上(参数port就是端口号)。客户端需要指定的端口号来访问服务器端程序,backlog用于指定在
* 服务器忙时,可以与之保持连接请求的等待客户数量,如果没有指定这个参数,默认为50
* ServerSocket(int port,int backlog,InetAddress bindAddr)bindAddr用于指定相关的IP地址,该构造方法的使用适用于计算机上有多块网卡和多个IP的情况
* 使用时可以明确规定ServerSocket在哪块网卡或IP地址上等待客户的连接请求。
*/
public static void main(String[] args) throws Exception {
// 创建TCPServer对象,并调用listen()方法
TCPServer tcpss=new TCPServer();
tcpss.listen();
}
}
/*//TCP服务端
class TCPServer{
private static final int PORT = 7788;//定义一个端口号
public void listen() throws Exception {
// 创建ServerSocket(服务器)对象,指定端口PORT,即7788
ServerSocket s = new ServerSocket(PORT);
// Socket accept()该方法用于等待客户端的连接,在客户端连接之前会一直处于阻塞状态,如果有客户端连接,就会返回一个与之对应的Socket对象,就是服务器也会创建一个Socket对象,去和客户端的Socket对象对应
// 调用ServerSocket的accept()方法接受客户端的请求,执行accept()方法之后程序会发生阻塞,直到客户端发出连接请求时,accept()会返回一个与之对应的Socket对象,用于和客户端实现通信
Socket client = s.accept();
OutputStream os = client.getOutputStream();//创建输出流对象,向客户端输出数据
System.out.println("开始与客户端交互数据");
// 当客户端连接到服务端时,向客户端输出数据。("传智博客欢迎你!").getBytes()将定义的字符串转换为字节数组
os.write( ("传智博客欢迎你!").getBytes() );
Thread.sleep(5000);//模拟执行其他功能占用的时间
System.out.println("结束与客户端交互数据");
os.close();//关闭缓冲区
client.close();//关闭客户端与服务器的连接
}
}*/
/*
* 上面的程序分别实现了服务器端程序和客户端程序,当一个客户端程序请求服务器端时,服务器端就会结束阻塞状态,完成程序的运行
* 实际上,很多服务器端程序都是允许被多个应用程序访问的,例如门户网站可以被多个用户同时访问,因此服务器都是多线程的
* 多个客户端访问同一个服务器端,服务器端为每个客户创建一个对应的Socket,并且开启一个新的线程使两个Socket(一个是客户端的,一个是服务器端的)建立专线进行通信
*/
//TCP服务端
class TCPServer{
private static final int PORT = 7788;//定义一个端口号
public void listen() throws Exception {
// 创建ServerSocket(服务器)对象,指定端口PORT,即7788
ServerSocket s = new ServerSocket(PORT);
// 使用while循环不停的接受客户端发送的请求
while(true) {
// Socket accept()该方法用于等待客户端的连接,在客户端连接之前会一直处于阻塞状态,如果有客户端连接,就会返回一个与之对应的Socket对象
// 调用ServerSocket的accept()方法接受客户端的请求,执行accept()方法之后程序会发生阻塞,直到客户端发出连接请求时,accept()会返回一个与之对应的Socket对象,用于和客户端实现通信
Socket client = s.accept();
// 下面的代码用来开启一个新的线程
new Thread() {
public void run() {
OutputStream os;//定义一个输出流对象
try {
os = client.getOutputStream();//获取客户端的输出流
System.out.println("开始与客户端交互数据");
os.write(("传智播客欢迎您!").getBytes());
Thread.sleep(5000);//使线程休眠5000毫秒
System.out.println("结束与客户端交互数据");
os.close();//关闭输出流
client.close();//关闭Socket对象
}catch(Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
}
再写客户端。(就是再建一个java文件)
package wangluobiancheng;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
/*
* Socket用于实现TCP客户端程序
* Socket()该构造方法在创建Socket对象时,并没有指定IP地址和端口号,也就意味着只创建了客户端对象,并没有连接任何服务器。
* 通过该构造方法创建对象后还需调用connect(SocketAddress endpoint)方法,才能完成与指定服务器端的连接。其中参数endpoint用于封装IP地址和端口号
*/
public static void main(String[] args) throws Exception {
TCPClient tcpc = new TCPClient();
tcpc.connect();//创建TCPClient对象,并调用connect()方法
}
}
class TCPClient{
private static final int PORT = 7788;//服务端的端口号
public void connect() throws Exception {
// Socket(InetAddress address,int port)该构造方法在创建Socket对象时,指明IP地址和端口号
// 创建一个Socket(客户端)并连接到给出地址和端口号的计算机
Socket client = new Socket(InetAddress.getLocalHost(),PORT);
InputStream is = client.getInputStream();//创建输入流对象,client.getInputStream()用来接受服务器发来的数据
// 定义1024个字节数组
byte[] buf = new byte[1024];
int len = is.read(buf);//将数据读取到缓冲区
System.out.println( new String(buf,0,len) );//将缓冲区中的数据打印
// 关闭Socket对象,即关闭连接,释放资源
client.close();
}
}
服务器文件执行后
客户端执行后