提到java的网络编程,大家肯定会想到TCP,UDP协议,下面对这两种协议进行相应介绍
1.TCP是一种面向连接的保证可靠传输的协议,通过TCP协议传输,得到的是一个顺序的无差错的数据流,发送方和接收方两个socket之间必须建立连接,一旦连接起来,双向均可以进行发送或接收操作
2.UDP是一种无连接的协议,每个数据包报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达时间以及内容的正确性都是不能保证的
也许你会问既然UDP是这么一个不可靠的协议,那为什么还有它的价值,原因有几个
a.可靠的传输必然是要付出代价的,对数据的校验必然占用计算机处理时间和网络带宽,因此TCP的传输效率不如UDP
b.在许多应用中没必要保证严格的传输可靠性,比如视频会议系统,只需保证连贯性就可以了,这种情况下使用UDP合理一些
下面是我通过TCP连接实现多线程之间通信的小例子
首先是客户端代码
服务器段代码
以上只是一个模拟线程通信的小例子,有些异常没有得到很好的处理,不足之处请见谅
下面是模拟UDP通信的例子
接收方
发送方
1.TCP是一种面向连接的保证可靠传输的协议,通过TCP协议传输,得到的是一个顺序的无差错的数据流,发送方和接收方两个socket之间必须建立连接,一旦连接起来,双向均可以进行发送或接收操作
2.UDP是一种无连接的协议,每个数据包报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达时间以及内容的正确性都是不能保证的
也许你会问既然UDP是这么一个不可靠的协议,那为什么还有它的价值,原因有几个
a.可靠的传输必然是要付出代价的,对数据的校验必然占用计算机处理时间和网络带宽,因此TCP的传输效率不如UDP
b.在许多应用中没必要保证严格的传输可靠性,比如视频会议系统,只需保证连贯性就可以了,这种情况下使用UDP合理一些
下面是我通过TCP连接实现多线程之间通信的小例子
首先是客户端代码
package com.lamp.client;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient extends JFrame {
private static final long serialVersionUID = 1164739305605633090L;
private Socket socket = null;
private JTextField text = new JTextField();
private JTextArea textArea = new JTextArea();
private DataOutputStream dos = null;
private DataInputStream dis = null;
private boolean flag = false;
public void launchFrame() {
this.setLocation(400, 400);
this.setSize(500, 300);
this.add(textArea, BorderLayout.NORTH);
this.add(text, BorderLayout.SOUTH);
this.textArea.setEditable(false);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
if (dos != null)
dos.close();
if (dis != null)
dis.close();
if (socket != null)
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.exit(0);
}
});
this.text.addActionListener(new MessageSendAction());
this.setVisible(true);
connect();
}
class MessageSendAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
String message = ChatClient.this.text.getText().trim();
text.setText("");
try {
dos.writeUTF(message); //从输入框中得到数据后发给服务器端
dos.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void connect() {
try {
socket = new Socket("127.0.0.1", 2222); //和服务器端连接
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
flag =true;
new Thread(new RecieveMessage()).start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class RecieveMessage implements Runnable { //监听服务器端发来的数据流
public void run() {
try {
while (flag) {
String message = dis.readUTF();
textArea.setText(textArea.getText() + message + "\n");
System.out.println("server message back" + message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ChatClient().launchFrame();
}
}
服务器段代码
package com.lamp.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ChatServer {
private ServerSocket ss = null;
private List<Client> clients = new ArrayList<Client>();
private boolean portFlag = false;
public ChatServer() {
try {
ss = new ServerSocket(2222);
portFlag = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void begin() {
try {
while (portFlag) {
Socket socket = ss.accept();
Client client = new Client(socket); // 和客户端连接并为每个客户端分配一个线程
new Thread(client).start();
clients.add(client);
System.out.println("one client connected");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Client implements Runnable { // 每个客户端的连接为一个Client线程
private Socket socket = null;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean flag = false;
public Client(Socket socket) {
this.socket = socket;
try {
dis = new DataInputStream(this.socket.getInputStream());
dos = new DataOutputStream(this.socket.getOutputStream());
flag = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (flag) {
String message = dis.readUTF();
if (message != null) {
for (int i = 0; i < clients.size(); i++) {
Client client = clients.get(i); // 服务器端得到客户端发来的数据并分发给每个连接的客户端
client.send(message);
}
System.out.println(message);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (dis != null)
dis.close();
if (dos != null)
dos.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void send(String message) {
try {
dos.writeUTF(message);
} catch (IOException e) {
clients.remove(this);
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ChatServer().begin();
}
}
以上只是一个模拟线程通信的小例子,有些异常没有得到很好的处理,不足之处请见谅
下面是模拟UDP通信的例子
接收方
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPTest2 {
public static void main(String[] args) throws Exception {
//接收消息,监听5000端口
DatagramSocket socket = new DatagramSocket(5000);
byte[] buffer = new byte[500];
DatagramPacket packet = new DatagramPacket(buffer, 500);
socket.receive(packet);
System.out.println(new String(buffer, 0, packet.getLength()));
//发送消息
String answer = "I am fine, thank you";
//通过发送过来的数据包能得到源地址和端口
DatagramPacket packet2 = new DatagramPacket(answer.getBytes(), answer
.length(), packet.getAddress(), packet.getPort());
socket.send(packet2);
socket.close();
}
}
发送方
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPTest1 {
public static void main(String[] args) throws Exception {
//发送消息,注意传输的数据不能超过64KB
DatagramSocket socket = new DatagramSocket();
String str = "How are you?";
DatagramPacket packet = new DatagramPacket(str.getBytes(),str
.length(),InetAddress.getByName("localhost"),5000);
socket.send(packet);
//接受消息
byte[] buffer = new byte[200];
DatagramPacket packet2 = new DatagramPacket(buffer,200);
socket.receive(packet2);
System.out.println(new String(buffer,0,packet2.getLength()));
socket.close();
}
}