JAVA网络编程

1、TCP程序的实现

2、将多线程应用在网络开发之中

3、UDP的程序实现


网络编程的基本概念:

网络:就是将物理上不在一起的主机进行互联。

在网络上的通讯需要使用协议,常见的通讯协议:TCP、UDP

* TCP:属于可靠的连接,使用三方握手的方式完成连接的确认。

* UDP:属于不可靠的连接

对于网络程序的开发有两种架构:

* C/S:客户端服务器端,对于这种程序需要开发两套代码,一套是客户端,另一套是服务器,维护也要两套。

* B/S:浏览器/服务器,就类似于论坛,开发和维护的时候只需要一套代码即可。


TCP程序的实现

在JAVA中,所有的网络开发包保存在java.net包中,在此包中可以使用ServerSocket、Socket类完成服务器和客户端的开发。

1、简单的Tcp程序

如果想要开发TCP程序,则首先开发服务器端,要使用ServerSocket进行客户端的连接接收,每一个客户端在程序上都使用Socket对象表示。

package wangluo;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
	public static void main(String args[]) throws IOException{
		ServerSocket serverSocket = new ServerSocket(8888);//在8888端口上开启服务
		Socket socket = serverSocket.accept();//接收客户端连接
		OutputStream outputStream = socket.getOutputStream();//得到客户端的输出流
		String code = "hello  world";//要发送的内容
		PrintStream printStream = new PrintStream(outputStream);
		printStream.print(code);
		printStream.close();
		outputStream.close();
		socket.close();
		serverSocket.close();
		
	}
}
如果此时要想进行连接的操作实验,则可以通过telnet命令完成。

那么此时就完成了一个服务器程序的开发,此程序执行完一次之后将关闭。那么现在的程序是通过telnet命令完成的服务器的访问,也可以通过单独的客户端程序编写代码进行访问。

package wangluo;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class ClientDemo {
	public static void main(String args[]) throws Exception{
		//表示连接的主机及端口
		Socket socket = new Socket("localhost", 8888);
		BufferedReader bufferedReader = null;
		InputStream inputStream = socket.getInputStream();
		bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
		//接收回应的内容
		String getStr = bufferedReader.readLine();
		System.out.println(getStr);
		bufferedReader.close();
		inputStream.close();
		socket.close();
	}
}


Echo 程序(回应程序)

下面通过ServerSocket和Socket类完成一个简单的echo程序,echo表示回应程序,输入的内容发送到服务器端之后,在前面加上“ECHO”的字符串再返回。

对于服务器端而言,客户端的输出是服务端的输入流,服务器端的输出流是客户端的输入流。

package wangluo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class EchoServer {
	public static void main(String args[]) throws IOException{
		ServerSocket serverSocket = new ServerSocket(8888);
		Socket socket = null;
		boolean flag = true;
		while(flag){
			System.out.println("等待客户端响应");
			socket = serverSocket.accept();
			InputStream inputStream = socket.getInputStream();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			OutputStream outputStream =socket.getOutputStream();
			PrintStream printStream = new PrintStream(outputStream);
			boolean temp= true;
			while(temp){
				String clientSendStr = bufferedReader.readLine();
				if(null==clientSendStr||"".equals(clientSendStr)){
					printStream.print("........");
					temp = false;
					break;
				}else if("bye".equals(clientSendStr)){
					printStream.print("bye");
					temp = false;
					break;
				}else{
					printStream.print("ECHO "+clientSendStr+"\r\n");
				}
				
			}
			
			printStream.close();
			bufferedReader.close();
			inputStream.close();
			outputStream.close();
			socket.close();
		} 
		serverSocket.close();
	}
}
那么,此时客户端的操作也应该是一样的,应该准备好输入流,而且现在的代码中存在了输入操作,所以要使用键盘输入信息。

package wangluo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class EchoClient {
	public static void main(String args[]) throws UnknownHostException, IOException{
		Socket socket = new Socket("localhost", 8888);
		
			BufferedReader bufferedReaderIN = new BufferedReader(new InputStreamReader(System.in));
			OutputStream outputStream = socket.getOutputStream();
			PrintStream printStream= new PrintStream(outputStream);
			InputStream inputStream = socket.getInputStream();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			boolean tag = true;
			while(tag){
				System.out.println("请输入要放松的内容");
				printStream.println(bufferedReaderIN.readLine());
				String str = bufferedReader.readLine();
				System.out.println("得到的内容是:"+str);
				System.out.println("————————————————————————————————————————————————");
			}
			socket.close();
			bufferedReader.close();
			inputStream.close();
			outputStream.close();
	}
}


但是,以上的程序只适合一个线程的使用,如果有多个用户,则肯定无法同时连接,这就是传统的单线程的操作,如果想实现多线程,则每一个客户端应该使用线程表示出来。

加入多线程

每一个客户端都使用一个线程进行表示。

package wangluo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class EchoThreadServer {
	private static boolean IS_OPEN_SERVER = true;// 服务器是否是开启的

	public static void main(String args[]) throws IOException {
		ServerSocket serverSocket = new ServerSocket(8888);
		while (IS_OPEN_SERVER) {
			new Thread(new ThreadServer(serverSocket.accept())).start();
		}
		serverSocket.close();
	}
}

class ThreadServer implements Runnable {
	private Socket socket;

	public ThreadServer(Socket socket) {
		this.socket = socket;
	}

	public void run() {
		try {
			//接收数据
			BufferedReader bufferedReader = new BufferedReader(
					new InputStreamReader(socket.getInputStream()));
			PrintStream printStream = new PrintStream(socket.getOutputStream());
			boolean IS_END = true;
			while(IS_END){
				String getCommand = bufferedReader.readLine();
				if(null==getCommand||"".equals(getCommand.trim())){
					printStream.println("客户端关闭");
					IS_END = false;
					break;
				}else if("bye".equals(getCommand)){
					printStream.println("客户端关闭");
					IS_END = false;
					break;
				}else{
					printStream.println("传递数据成功啦"+getCommand);
				}
			}
			printStream.close();
			bufferedReader.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

一个服务器应该实现多线程。


UDP程序实现


UDP程序使用数据的形式出现,需要使用以下两个类:

* 数据报的内容: DatagramPacket

* 发送和接收数据报: DatagramSocket

在开发TCP程序的时候,是先要有服务器端,之后再进行客户端的开发,而UDP要运行的时候则应该先运行客户端,之后再运行服务器端


客户端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPReceive {
	public static void main(String[] args) throws IOException {
		//客户端在3000端口等待服务器发来的信息
		DatagramSocket socket = new DatagramSocket(3000);
		//开辟1024空间
		DatagramPacket datagramPacket = new DatagramPacket(new byte[1024], 1024);
		socket.receive(datagramPacket);
		System.out.println("接收到的内容是: "+new String(datagramPacket.getData()));
	}

}


服务器端:

package wangluo;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class UDPSend {
	public static void main(String[] args) throws IOException {
		//服务器端在9000端口等待接收服务器发来的信息
		DatagramSocket datagramSocket = new DatagramSocket(9000);
		String sendStr = "hello world";
		DatagramPacket datagramPacket = 
				new DatagramPacket(sendStr.getBytes(), 0, sendStr.length(), InetAddress.getLocalHost(),3000);
		datagramSocket.send(datagramPacket);
	}

}



总结:

1、TCP程序的开发依靠   ServerSocket、Socket

2、UDP程序的开发依靠   DatagramSocket 、DatagramPacket



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值