UDP,简单聊天程序
TCP,上传文件到服务端
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();
}
}
TCP,上传文件到服务端
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();
}
}