第二十一天总结
/*
用UDP实现多人聊天窗口,初级版本
在同一个窗口实现发送和接受,就要想到多线程的应用
*/
import java.io.*;
import java.net.*;
/*
发送方
创建发送方的步骤:
1.创建UDP的socket服务
2.建立数据包
3.通过UDP的socket服务对象调用send方法,将已定义好的数据包发送到
目的地
*/
class ThreadSend implements Runnable//覆盖Runnable中的run方法
{
private DatagramSocket ds;
ThreadSend(DatagramSocket ds)
{
this.ds=ds;
}
public void run()//要覆盖run方法,异常就必须处理,不能
抛出
{
try
{
BufferedReader br=new BufferedReader(
new InputStreamReader
(System.in));//键盘录入
String line=null;
while ((line=br.readLine())!=null)
{
if ("over".equals(line))//发送
方结束标记
break;
byte[] by=line.getBytes();//数
据包对象要接受字节数组
/*
创建一个数据包对象
*/
DatagramPacket dp=new
DatagramPacket
(by,by.length,InetAddress.getByName("192.168.1.151"),10003);
ds.send(dp);//发送数据包
}
ds.close();
}
catch (Exception e)
{
System.out.println(e.toString());
}
}
}
/*
接收方
创建接收方的步骤:
1.创建UDP的socket服务对象,并监听一个端口,这是因为要明确
哪一个端口进来的数据时该接收端可以进行处理的
2.创建一个数据包,用来存储接收到的数据。
之所以将数据存入一个数据包中,是因为数据有多项数据信息,比如说
:源地址,目的地址,端口
或者数据主体内容等需要被解析
3.将接收到的数据存入已经创建好的数据包中,通过UDP的socket服务对
象,调用receive方法
4.通过指挥数据包,就可以获取数据包中的数据内容
*/
class ThreadReceive implements Runnable
{
private DatagramSocket ds;
ThreadReceive(DatagramSocket ds)
{
this.ds=ds;
}
public void run()
{
try
{
while (true)//这里是为了方便,所以就没
有判断去关闭接收方
{
byte[] by=new byte[1024];//创建
一个缓冲区用于存放接受到的数据
DatagramPacket dp=new
DatagramPacket(by,by.length);//创建接收方数据包
ds.receive(dp);//接收数据
String ip=dp.getAddress
().getHostAddress();//获取发送方IP地址
String str=new String
(dp.getData(),0,dp.getLength());//获取发送的内容
int port=dp.getPort();//获取端
口号
System.out.println("接收
方:"+ip+":"+str+"----port:"+port);
}
}
catch (Exception e)
{
System.out.println(e.toString());
}
}
}
/*
通过开启两个线程,就可以实现在同一个窗口进行发送和接收
*/
class SendReceive
{
public static void main(String[] args)throws Exception
{
DatagramSocket ds=new DatagramSocket();
DatagramSocket dr=new DatagramSocket(10003);
new Thread(new ThreadSend(ds)).start();//多线程
应用
new Thread(new ThreadReceive(dr)).start();
}
}
________________________________________________
/*
编写一个可以进行大写转化的服务器
客户端的编写:
1.获取键盘录入,
2.将键盘录入的数据写入到socket流
3.读取服务端发回的大写数据,显示在客户端的控制台
服务端:
1.监听一个端口
2.获取客户端对象
3.读取socket流中的客户端发过来的小写数据
4.将其转化成大写发回客户端
思考:
这是一个IO流的操作,对于客户端来讲,源就是键盘,目的就是socket
流,因为
操作的多是文本数据,所以使用字符流更方便高效
程序在运行时会因为read().readLine()这类阻塞方式的存在而阻塞,
*/
import java.net.*;
import java.io.*;
/*
客户端构建流程:
1.建立客户端socket服务,并去连接指定的服务端
2.通过socket对象获取socket流中的输出流对象
3.通过socket输出流对象将数据写入socke
*/
class ClinetText
{
private Socket s;
ClinetText(Socket s)
{
this.s=s;
}
public void clinet()throws Exception
{
BufferedReader br=new BufferedReader(
new InputStreamReader(System.in));//创
建流获取键盘录入
BufferedWriter bw=new BufferedWriter(
new OutputStreamWriter
(s.getOutputStream()));//创建流用于给socket流输入数据
BufferedReader br1=new BufferedReader(
new InputStreamReader(s.getInputStream
()));//创建流用于输出从服务端返回的数据
String line=null;
while ((line=br.readLine())!=null)
{
if ("over".equals(line))
break;
bw.write(line);
bw.newLine();//必须回车确定改行结束标记
bw.flush();//用到缓冲区必须刷新
String str=br1.readLine();
System.out.println("服务端反馈:"+str);
}
br.close();
s.close();
}
}
/*
服务端构建流程
1.建立服务端socket服务,并监听一个端口,以取客户端发来的数据
2.获取连接进来的socket对戏那个,为了获取socket的流,因为数据信
息都存储在那
*/
class ServerText
{
private ServerSocket ss;
ServerText(ServerSocket ss)
{
this.ss=ss;
}
public void server()throws Exception
{
Socket s=ss.accept();//通过ServerSocket对象的
accept方法接受客户端的Socket对象
String ip=s.getInetAddress().getHostAddress
();//通过Socket对象中的Socket流获取所需数据
System.out.println(ip+"---connected");
BufferedReader br=new BufferedReader(
new InputStreamReader(s.getInputStream
()));//创建流用于输出客户端通过socket对象发送来的数据
BufferedWriter bw=new BufferedWriter(
new OutputStreamWriter
(s.getOutputStream()));//创建流往socket中输入服务端回馈信息
String line=null;
while ((line=br.readLine())!=null)
{
System.out.println("客户端发
送:"+line);
bw.write(line.toUpperCase());
bw.newLine();//定义结束标记
bw.flush();
}
s.close();
ss.close();
}
}
/*
在调用的时候一定要先开启服务端
开启服务端
*/
class TCPservertest
{
public static void main(String[] args)throws Exception
{
ServerSocket ss=new ServerSocket(10004);
ServerText st=new ServerText(ss);
st.server();
}
}
/*
开启客户端
*/
class TCPclinettest
{
public static void main(String[] args) throws Exception
{
Socket s=new Socket("192.168.1.151",10004);
ClinetText ct=new ClinetText(s);
ct.clinet();
}
}