java之 23天 UDP,TCP练习 (三)

[size=medium][b]UDP,简单聊天程序[/b][/size]



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/**
* 编写一个聊天程序
* 有收数据的部分,和发送数据的部分
* 这两部分需要同时执行
* 那就需要用到多线程技术
* 一个线程控制收,一个线程控制发.
*
* 因为收和发动作是不一致的,所以需要定义run方法
* 而且这两个方法需要封装到不同的类中
*/

class Send implements Runnable{
private DatagramSocket ds;
Send(DatagramSocket ds){
this.ds=ds;
}

public void run(){
try {
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

String line=null;
while((line=bufr.readLine())!=null){
if("886".equals(line))
break;
byte[] buf=line.getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.121"),10000);

ds.send(dp);
}
ds.close();
} catch (IOException e) {
throw new RuntimeException("发送端失败!");
}

}

}
class Rece implements Runnable{
private DatagramSocket ds;
Rece(DatagramSocket ds){
this.ds=ds;
}

public void run(){
try {

while(true){
byte[]buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
ds.receive(dp);

String ip=dp.getAddress().getHostAddress();
String data=new String(dp.getData(),0,dp.getLength());

System.out.println(ip+"::"+data);
}
} catch (IOException e) {
throw new RuntimeException("接受失败!");
}
}
}


public class Chatdemo {

public static void main(String[] args) throws SocketException {

DatagramSocket sendSocket=new DatagramSocket();
DatagramSocket receSocket=new DatagramSocket(10000);

new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();

}

}


[size=medium][b]TCP,上传文件到服务端[/b][/size]


import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 将客户端的一个文件复制到服务端
*
* 必须加入结束标记:否则 程序 都会 等着
* 1.第一种:加入自定义标记 "over" : 不靠谱, 容易传输的数据 重复,这样 造成服务端 提前结束
* 2.加入 时间戳 客户端 在开始传输数据的时候,首先就传输一个时间戳 ,作为标记;(发现 流对象 用的特别多)
* 3.标准方式: socket 的 shutdownOutput() shutdowninput()
*/
class TextClient{

public static void main(String[] args) throws IOException{

Socket s=new Socket("192.168.1.121",1000);

/*//方法二: 时间戳
DataOutputStream dos=new DataOutputStream(s.getOutputStream());
long time=System.currentTimeMillis();
dos.writeLong(time);*/

BufferedReader bufr=new BufferedReader(new FileReader("E:\\workspace4\\exam\\src\\com\\itheima\\day23\\TcpDemo3.java"));

PrintWriter out=new PrintWriter(s.getOutputStream(),true);
//out.println(time+""); 方法二: 这样也行

String line=null;
while((line=bufr.readLine())!=null){
out.println(line);
}
/*//方法一: 由于没有结束标记 最后 两个程序 "都等着了" 容易和文本中的数据重复 如果文本中有 over呢 这样 服务器端就会提前 结束,并发生 "上传成功"
out.println("over");
//out.println(time+""); 方法二: 这样也行
//方法二: 时间戳
dos.writeLong(time);*/

//方法三:
s.shutdownOutput();// 关闭客户端的额输出信息 服务端不用做什么 ,会自动识别 客户端 已经输出完毕.

BufferedReader bufs=new BufferedReader(new InputStreamReader(s.getInputStream()));
String str=bufs.readLine();
System.out.println(str);
bufr.close();

//dos.close();

s.close();
}

}

class TextServer{
public static void main(String[] args) throws IOException{
ServerSocket ss=new ServerSocket(1000);
Socket s=ss.accept();

String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"..connected");
/*
//方法二: 开始前就读取 客户端发送过来的标记
DataInputStream dis=new DataInputStream(s.getInputStream());
long time=dis.readLong();
*/
BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));

PrintWriter outf=new PrintWriter(new FileWriter("E:\\server.txt"),true);

String line=null;
while((line=bufr.readLine())!=null){
/*if("over".equals(line)) //方法一: 加入标记后就 可以跳出了 "等待了" 发现这种标记容易重复
break;
if(String.valueOf(time).equals(line)) //方法二: 标记
break; */

outf.println(line);
}

PrintWriter out=new PrintWriter(s.getOutputStream(),true);
out.println("上传成功");

outf.close();
s.close();

}

}

你可能感兴趣的:(java)