java网络编程——TCP、UDP程序设计

本文详细介绍了Java中TCP和UDP程序设计。通过示例代码展示了如何使用Socket和ServerSocket创建TCP服务器和客户端,包括ECHO程序的实现,并讨论了TCP的C/S架构。同时,文章也提及了UDP的简单应用,强调其在性能和可靠性之间的权衡。
摘要由CSDN通过智能技术生成

本节目标:

了解Socket与ServerSocket类的作用

掌握ECHO程序的开发

将多线程应用在TCP程序上实现多用户操作

1.TCP程序设计

在java中使用Socket(套接字)完成TCP程序的开发,使用此类可以方便的建立可靠的、双向的、持续的、点对点的通讯连接。

在Socket的程序开发中,服务器端使用ServerSocket等待客户端的连接,对于java的网络程序而言,每一个客户端都使用一个Socket对象表示。


在java的网络程序中,客户端只要符合连接的通讯协议,那么服务器端都可以进行接收。

ServerSocket类主要用在服务器端程序的开发上,用于接收客户端的连接请求。

ServerSocket(int port) 
          创建绑定到特定端口的服务器套接字。


在服务器端每次运行时都要使用accept()方法等待客户端连接,此方法执行后服务器端进入阻塞状态,直到客户端连接后程序才会向下继续执行,此方法返回值类型是Socket,每一个Socket代表一个客户端对象。

Socket(String host, int port) 
          创建一个流套接字并将其连接到指定主机上的指定端口号。


服务器端与客户端的通讯:


public class HelloServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8888); // 创建绑定到8888端口的服务器套接字
Socket client = server.accept(); //客户端
System.out.println("服务器运行,等待连接...");
PrintStream out = new PrintStream(client.getOutputStream());
String str = "hello world";
out.print(str);
client.close();
server.close();
}

}

telnet localhost 8888

结果运行:


服务器将内容发送到了客户端后,客户端断开与服务器的连接。

public class HelloClient {
public static void main(String[] args) throws Exception, IOException {
Socket client = new Socket("localhost", 8888);
BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
String str = buf.readLine();
System.out.println("客户端接收的内容:" + str);
buf.close();
client.close();
}

}

运行结果:

客户端接收的内容:hello world

从以上可以发现,该架构为C/S架构,即客户端/服务器架构,需要编写和维护两套代码代码。另外一种B/S架构,即浏览器/服务器架构,只需维护一套代码即可。

案例:Echo程序

服务器端程序

public class HelloServer {
public static void main(String[] args) throws Exception {
ServerSocket server = null; //声明ServerSocket类
Socket client = null; //客户端
BufferedReader buf = null;//接收输入流
PrintStream out = null; //打印流输出
server = new ServerSocket(8888);//服务器监听8888端口
boolean f = true;
while(f){
System.out.println("服务器正在运行,等待客户端连接。");
client = server.accept();//得到连接,进入阻塞状态
out = new PrintStream(client.getOutputStream());//接收客户端的输入信息
buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
boolean flag = true; //标志位,可以一直接收和回应
while(flag){
String str = buf.readLine();
if (str == null || "".equals(str)) {
flag = false;
}else{
if("bye".equals(str)){
flag = false;
}else{
out.print("ECHO:" + str);
}
}
}
client.close();
}
server.close();
}

}

客户端程序

public class HelloClient {
public static void main(String[] args) throws Exception, IOException {
Socket client = null; //客户端
client = new Socket("localhost", 8888);
BufferedReader buf = null;//一次性接收
PrintStream out = null; //发送数据
BufferedReader input = null; //接收键盘数据

input = new BufferedReader(new InputStreamReader(System.in));
buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintStream(client.getOutputStream());

boolean flag = true;
while(flag){
System.out.println("输入信息:");
String str = input.readLine();
out.print(str);
if ("bye".equals(str)) {
flag = false;
}else{
String echo = buf.readLine();
System.out.println(echo);
}
}
buf.close();
client.close();
}

}


加入多线程:

public class EchoServer {
public static void main(String[] args) throws Exception {
ServerSocket server = null; //声明ServerSocket类
Socket client = null; //客户端
server = new ServerSocket(8888);//服务器监听8888端口
boolean f = true;
while(f){
System.out.println("服务器正在运行,等待客户端连接。");
client = server.accept();//得到连接,进入阻塞状态
new Thread(new EchoThread(client)).start(); //启动多线程
}
server.close();
}

}

public class EchoThread implements Runnable {
private Socket client = null;
public EchoThread(Socket client) {
this.client = client;
}
@Override
public void run() {
BufferedReader buf = null;// 接收输入流
PrintStream out = null; // 打印流输出
try {
out = new PrintStream(client.getOutputStream());// 接收客户端的输入信息
buf = new BufferedReader(new InputStreamReader(
client.getInputStream()));
boolean flag = true; // 标志位,可以一直接收和回应
while (flag) {
String str = buf.readLine();
if (str == null || "".equals(str)) {
flag = false;
} else {
if ("bye".equals(str)) {
flag = false;
} else {
out.print("ECHO:" + str);
}
}
}
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public class EchoClient {
public static void main(String[] args) throws Exception, IOException {
Socket client = null; //客户端
client = new Socket("localhost", 8888);
BufferedReader buf = null;//一次性接收
PrintStream out = null; //发送数据
BufferedReader input = null; //接收键盘数据

input = new BufferedReader(new InputStreamReader(System.in));
buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintStream(client.getOutputStream());

boolean flag = true;
while(flag){
System.out.println("输入信息:");
String str = input.readLine();
out.print(str);
if ("bye".equals(str)) {
flag = false;
}else{
String echo = buf.readLine();
System.out.println(echo);
}
}
buf.close();
client.close();
}

}

2.UDP设计

TCP虽然可靠,但是浪费系统性能,为了减少这种开销,使用UDP,服务器端发送的消息,客户端不一定接收到,在聊天工具中被广泛使用。

使用DatagramPacket包装一条要发送的消息, DatagramSocket用于完成信息的发送操作。

 

public class UDPServer{
public static void main(String args[]) throws Exception{ // 所有异常抛出
DatagramSocket ds = null ; // 定义发送数据报的对象
DatagramPacket dp = null ; // 声明DatagramPacket对象
ds = new DatagramSocket(3000) ; // 服务端在3000端口上等待服务器发送信息\
String str = "hello World!!!" ;
dp = new DatagramPacket(str.getBytes(),str.length(),InetAddress.getByName("localhost"),9000) ; // 所有的信息使用buf保存
System.out.println("发送信息。") ;
ds.send(dp); // 发送信息出去
ds.close() ;
}

}

public class UDPServer{
public static void main(String args[]) throws Exception{ // 所有异常抛出
DatagramSocket ds = null ; // 定义发送数据报的对象
DatagramPacket dp = null ; // 声明DatagramPacket对象
ds = new DatagramSocket(3000) ; // 服务端在3000端口上等待服务器发送信息\
String str = "hello World!!!" ;
dp = new DatagramPacket(str.getBytes(),str.length(),InetAddress.getByName("localhost"),9000) ; // 所有的信息使用buf保存
System.out.println("发送信息。") ;
ds.send(dp); // 发送信息出去
ds.close() ;
}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值