9-7. 说明一个客户端如何从服务器上读取一行文本。
- TCP/IP的方式是:客户端与服务器端成功握手以后,从Socket中得到数据输入流并用相应的包装器进行包装,以输入流中相应的read方法来读取一行的文本。
- UDP数据报的方式是:建立数据报的DatagramSocket对象以后,调用DatagramSocket对象的receive方法来等待服务器的数据到来,接收到数据以后用DatagramPacket对象的getData方法来将接收到的数据提取出来。
9-9. 采用套接字的连接方式编写一个程序,允许客户向服务器提出一个名字,如果这个文件存在,就把文件内容发送给客户,否则回答文件不存在。
程序代码如下
//客户端
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import javax.swing.JFrame;
public class TranFileClient extends JFrame implements ActionListener {
Button btn;
TextField tf;
public TranFileClient(){
//布局
super("要接收的文件名");
setBounds(400,400,300,100);
setVisible(true);
btn=new Button("接收");
tf=new TextField(7);
setLayout(new FlowLayout());
add(tf);
add(btn);
btn.addActionListener(this);
validate();
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0); }
});
}
public static void main(String[] args){
new TranFileClient();
}
/* (non-Javadoc)
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent arg0) {
try {
Socket st = new Socket("localhost",3997);
//给服务器文件名
DataOutputStream outServ =new DataOutputStream( st.getOutputStream());
outServ.writeUTF(tf.getText().trim());
//读服务器的消息
FileOutputStream out = new FileOutputStream(tf.getText().trim());
InputStream netin = st.getInputStream();
InputStream in = new DataInputStream(new BufferedInputStream(netin));
System.out.println("geting data.....");
byte[] buf=new byte[2048];
//
int num = in.read(buf);
while(num != -1){
out.write(buf, 0, num);
num = in.read(buf);
}
//取出服务器的状态
String str=new String(buf);
if(TranFileServer.PROP.equals(str.trim())){
tf.setText("文件没有找到!");
}
in.close();
out.close();
outServ.close();
System.out.println("recieved over.....");
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器
import java.net.ServerSocket;
import java.net.Socket;
import java.io.*;
public class TranFileServer {
//查找的文件的目录
final static String PATH = "d:/src";
final static String PROP = "NO";
boolean isExist = false;
public TranFileServer() {
init();
}
private void init() {
ServerSocket server;
Socket st;
String s = null;
try {
server = new ServerSocket(3997);
System.out.println("waiting client connect");
st = server.accept();
//读客户端来的文件名
try {
DataInputStream in = new DataInputStream(st.getInputStream());
while (true) {
s = in.readUTF();
if (s != null)
break;
}
System.out.println(s);
} catch (IOException e) {
System.out.println("ERRO:" + e);
throw e;
}
doCheck(s);
if (isExist) {
FileInputStream fos = new FileInputStream(PATH+"/"+s);
OutputStream netout = st.getOutputStream();
DataOutputStream doc = new DataOutputStream(
new BufferedOutputStream(netout));
System.out.println("sending data....");
byte[] buf = new byte[2048];
int num = fos.read(buf);
while (num != -1) {
doc.write(buf, 0, num);
doc.flush();
num = fos.read(buf);
}
fos.close();
doc.close();
}else{
OutputStream netout = st.getOutputStream();
DataOutputStream doc = new DataOutputStream(
new BufferedOutputStream(netout));
doc.write(PROP.getBytes());
doc.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 文件是否存在判断
*
* @param s
* @return
*/
private void doCheck(String s) {
boolean isExist;
//文件是否存在
File file = new File(PATH);
String[] filenames = file.list();
for (int i = 0; i < filenames.length; i++) {
String str = filenames[i];
if (str.equals(s)) {
this.isExist = true;
return;
}
}
}
public static void main(String[] args) {
new TranFileServer();
}
}
9-10. 写出使用多线程使得一个服务器同时为多个客户程序服务的基本框架。
程序代码如下
/**
* 多客户端一个服务器的例子
*/
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class C_client extends Frame implements ActionListener {
TextArea txt1;
Button btn;
Panel p;
int port;
DataInputStream in = null; //数据输入流
DataOutputStream out = null; //数据输出流
Socket c_socket; //套接字
InputStream in_data; //接收到的输入流
OutputStream out_data; //发送的输出流
String str; //存放接收的数据
int i = 0;
C_client() {
super("客户端");
setSize(300, 200);
setVisible(true);
txt1 = new TextArea(5, 4);
add(txt1, BorderLayout.CENTER);
p = new Panel();
add(p, BorderLayout.NORTH);
btn = new Button("连接");
p.add(btn);
btn.addActionListener(this);
validate();
}
public static void main(String[] args) {
new C_client();
}
public void actionPerformed(ActionEvent eee) {
try {
c_socket = new Socket("127.0.0.1", 4321);
} catch (IOException e) {
e.printStackTrace();
}
try {
in_data = c_socket.getInputStream();
out_data = c_socket.getOutputStream();
in = new DataInputStream(in_data);
out = new DataOutputStream(out_data);
int p1 = c_socket.getPort();
int p2 = c_socket.getLocalPort();
txt1.append("获取到对方的端口号: " + p1 + "\n");
txt1.append("本机的端口号: " + p2 + "\n");
} catch (IOException e) {
e.printStackTrace();
}
try {
str = in.readUTF();
txt1.append("客户收到:" + str + "\n");
if (i > 10) {
out.writeUTF("end");
c_socket.close();
System.exit(0);
}//发出end信息
else {
out.writeUTF("I am Client");
i++;
}
} catch (IOException e) {
System.out.println("ddd");
}
}
}
/**
* 多客户端一个服务器的例子
*/
import java.net.*;import java.io.*;
import java.awt.*;import java.awt.event.*;
class S_server extends Frame implements ActionListener,Runnable
{
ServerSocket s_socket; //服务器端套接字
Socket c_socket; //套接字
DataInputStream in=null; //数据输入流
DataOutputStream out=null; //数据输出流
InputStream in_data; //接收到的输入流
OutputStream out_data; //发送的输出流
int i=0; //计数(连接的客户数)
String str;
TextArea txt1;
Button btn;
Panel p;
S_server()
{
super("server");
setSize(300,200);
setVisible(true);
txt1=new TextArea(5,4);
add(txt1,BorderLayout.CENTER);
p=new Panel();
add(p,BorderLayout.NORTH);
btn=new Button("开始监听端口");
p.add(btn);
validate();
btn.addActionListener(this);
}
public void actionPerformed(ActionEvent eee)
{
try{
s_socket=new ServerSocket(4321);
while(true)
{
c_socket=s_socket.accept();
Thread t=new Thread(this);
t.start();
i++;
}
}catch(IOException e){ }
}
//线程
public void run()
{
try {
while(true)
{
in_data=c_socket.getInputStream();
out_data=c_socket.getOutputStream();
in=new DataInputStream(in_data);
out=new DataOutputStream(out_data);
out.writeUTF("Hello,我是服务器");
str=in.readUTF();
if (str.equals("end"))
{//接收到end信息,则断开连接
in.close();
out.close();
c_socket.close();
}
txt1.append("第"+i+"个客户发来:"+str+"\n");
Thread.sleep(200);
} //while_end
}
catch(IOException e){
e.printStackTrace();
}
catch(Exception ee){
ee.printStackTrace();
} //Thread_catch
}
public static void main(String[] args)
{
new S_server();
}
}
9-11. 编写简易云计算程序,一个客户同时有多个服务器为他提供服务的基本框架。
程序代码如下
/**
* 一个客户端多个服务器的例子
*/
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class C_client1 extends Frame implements ActionListener, Runnable {
TextArea txt1;
Button btn;
Panel p;
int port;
DataInputStream in = null; //数据输入流
DataOutputStream out = null; //数据输出流
//套接字
InputStream in_data; //接收到的输入流
OutputStream out_data; //发送的输出流
String str; //存放接收的数据
String[] IP = new String[] { "127.0.0.1", "127.0.0.2", "127.0.0.3" }; //服务器的IP
int IPi = 0; //IP的下标
C_client1() {
super("客户端");
setSize(300, 200);
setVisible(true);
txt1 = new TextArea(5, 4);
add(txt1, BorderLayout.CENTER);
p = new Panel();
add(p, BorderLayout.NORTH);
btn = new Button("连接");
p.add(btn);
btn.addActionListener(this);
validate();
}
public static void main(String[] args) {
new C_client1();
}
public void actionPerformed(ActionEvent eee) {
Thread t1 = new Thread(this);
t1.start();
Thread t2 = new Thread(this);
t1.start();
Thread t3 = new Thread(this);
t1.start();
}
public void run() {
Socket c_socket = null;
try {
c_socket = new Socket(IP[IPi++], 4321);
} catch (IOException e) {
e.printStackTrace();
}
try {
in_data = c_socket.getInputStream();
out_data = c_socket.getOutputStream();
in = new DataInputStream(in_data);
out = new DataOutputStream(out_data);
String p1 = c_socket.getInetAddress().getHostAddress();
int p2 = c_socket.getLocalPort();
txt1.append("获取到对方的IP: " + p1 + "\n");
txt1.append("本机的端口号: " + p2 + "\n");
str = in.readUTF();
txt1.append("客户收到:" + str + "\n");
out.writeUTF("I am Client");
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 一个客户端多个服务器的例子
*/
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class S_server1 extends Frame implements ActionListener{
ServerSocket s_socket; //服务器端套接字
Socket c_socket; //套接字
DataInputStream in = null; //数据输入流
DataOutputStream out = null; //数据输出流
InputStream in_data; //接收到的输入流
OutputStream out_data; //发送的输出流
int i = 0; //计数(连接的客户数)
String str;
TextArea txt1;
Button btn;
Panel p;
S_server1() {
super("server");
setSize(300, 200);
setVisible(true);
txt1 = new TextArea(5, 4);
add(txt1, BorderLayout.CENTER);
p = new Panel();
add(p, BorderLayout.NORTH);
btn = new Button("开始监听端口");
p.add(btn);
validate();
btn.addActionListener(this);
}
public void actionPerformed(ActionEvent eee) {
try {
s_socket = new ServerSocket(4321);
c_socket = s_socket.accept();
in_data = c_socket.getInputStream();
out_data = c_socket.getOutputStream();
in = new DataInputStream(in_data);
out = new DataOutputStream(out_data);
out.writeUTF("Hello,我是服务器");
str = in.readUTF();
in.close();
out.close();
c_socket.close();
} catch (IOException e) {
}
//Thread_catch
}
public static void main(String[] args) {
new S_server();
}
}