`
liaokang.java
  • 浏览: 152177 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

java之网络编程

    博客分类:
  • java
阅读更多
提到java的网络编程,大家肯定会想到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();
	}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics