十五、网络通信
1.仿照例15.4,编写基于TCP Socket的多客户/服务器通信程序。
//ServerThread.java
import java.io.*;
import java.net.*;
public class ServerThread extends Thread{
Socket socket=null;
int clientnum; //保存本进程的客户序号
public ServerThread(Socket socket,int num) {
this.socket=socket;
clientnum=num+1;
}
public void run() { //线程主体
try{
String line;
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter os=new PrintWriter(socket.getOutputStream());
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Client:"+ clientnum +is.readLine());
line=sin.readLine();
while(!line.equals("bye")){
os.println(line);
os.flush();
System.out.println("Server:"+line);
System.out.println("Client:"+ clientnum +is.readLine());
line=sin.readLine();
}
os.close();
is.close();
socket.close();
}catch(Exception e){
System.out.println("Error:"+e);
}
}
}
//TalkClient.java
import java.io.*;
import java.net.*;
public class TalkClient {
public static void main(String args[]) {
try{
//向本机的4700端口发出客户请求
Socket socket=new Socket("127.0.0.1",4800);
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
PrintWriter os=new PrintWriter(socket.getOutputStream());
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String readline;
readline=sin.readLine();
while(!readline.equals("bye")){
os.println(readline);
os.flush();
System.out.println("Client:"+readline);
System.out.println("Server:"+is.readLine());
readline=sin.readLine();
}
os.close();
is.close();
socket.close();
}catch(Exception e) {
System.out.println("Error"+e);
}
}
}
//MultiTalkServer.java
import java.io.*;
import java.net.*;
import ServerThread;
public class MultiTalkServer{
static int clientnum=0; //记录当前客户的序号
public static void main(String args[]) throws IOException {
ServerSocket serverSocket=null;
try{
serverSocket=new ServerSocket(4800);
}catch(IOException e) {
System.out.println("Could not listen on port:4700.");
System.exit(-1); //退出
}
while(true){
new ServerThread(serverSocket.accept(),clientnum).start();
clientnum++;
}
serverSocket.close();
}
}
2.仿照例15.5,编写基于UDP数据报的多客户/服务器通信程序。
//QuoteServerThread.java
import java.io.*;
import java.net.*;
import java.util.*;
public class QuoteServerThread extends Thread{ protected DatagramSocket socket=null;
protected BufferedReader in=null;
protected boolean moreQuotes=true;
public QuoteServerThread() throws IOException {
this("QuoteServerThread");
}
public QuoteServerThread(String name) throws IOException {
super(name);
socket=new DatagramSocket(4445);
in= new BufferedReader(new InputStreamReader(System.in));
}
public void run()
{
while(moreQuotes) {
try{
byte[] buf=new byte[256]; //创建缓冲区
DatagramPacket packet=new DatagramPacket(buf,buf.length);
socket.receive(packet);
System.out.println(new String(packet.getData()));
String dString= in.readLine();
if(dString.equals("bye")){moreQuotes=false;}
buf=dString.getBytes();
InetAddress address=packet.getAddress();
int port=packet.getPort();
packet=new DatagramPacket(buf,buf.length,address,port);
socket.send(packet);
}catch(IOException e) {
e.printStackTrace();
moreQuotes=false;
}
}
socket.close();
}
}
//QuoteClient .java
import java.io.*;
import java.net.*;
import java.util.*;
public class QuoteClient {
public static void main(String[] args) throws IOException
{
if(args.length!=1){
System.out.println("Usage:java QuoteClient <hostname>");
return;
}
DatagramSocket socket=new DatagramSocket();
byte[] buf=new byte[256];
InetAddress address=InetAddress.getByName(args[0]);
DatagramPacket packet=new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
packet=new DatagramPacket(buf,buf.length);
socket.receive(packet);
String received=new String(packet.getData());
System.out.println("Quote of the Moment:"+received );
socket.close();
}
}
public class QuoteServer{
public static void main(String args[]) throws java.io.IOException
{
new QuoteServerThread().start();//启动一个QuoteServerThread线程
}
}
3.基于TCP Socket的C/S通信与基于UDP数据报的C/S通信有哪些区别?Java分别提供了哪些支持?
TCP协议-Socket
UDP协议-DatagramSocket与DatagramPacket
DatagramSocket:用于发送或接收数据报,是数据报投递服务的一个发送或接收点。
DatagramPacket:用来表示一个数据报