tcp(socket)
tcp:传送数据安全,丢包会从发(速度慢)
网络编程要有服务器端,客户端
直接看栗子:
服务器端:
/*
* 服务器端:
* 用ServerSocket来创建服务器端,用Socket来连接两端(socket可以说就是一个连接两端的管道)
* 1,创建服务器端口,端口号不要使用1024以下的
* 2,监听接受到的客户端(一般服务器是不能停止的,需要不停的监听连接的客户端,可以用个死循环)
* 3,两端的数据通信:getInputStream(),getOutputStream()可以获取Soket中的输入流和输出流,可以用
* 输入流和输出流来相互传送数据
* 4,最后要关闭ServerSocke和连接的Socket。
*
* ★关闭的最佳方法:当客户端要关闭时,先给服务器发送一条要关闭,这时服务器在释放资源,释放完再给客户端
* 传回资源释放完毕的消息,这是客户端接受到消息时在关闭连接socket(管道)。
* */
class TcpServer{
public static void main(String[] args) {
ServerSocket ss =null;
Socket s = null; //接收到的客户端
//输入流和输出流
BufferedReader br = null;
PrintWriter pw = null;
try {
//1,创建服务器端口
ss = new ServerSocket(9999);
//死循环不停的监听
while(true){
try {
//2,接收连接的客户端放在s中
s = ss.accept();
//3,获取socket中的输入流和输出流
//br是字符流,getInputStream()是字节流,需要使用转换流
//pw是有带缓冲的,需要用true来刷新
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw = new PrintWriter(s.getOutputStream(),true);
//我这里是不停的读取客户端传来的数据
//然后将接受到的数据在传给客户端
String str = null;
while((str=br.readLine())!=null){ //br读取数据
//★最佳关闭方法:
//接受到客户端quit是客户端要关闭socket
if(str.trim().equals("quit")){
//在这里可以释放资源
//释放完给客户端发条可以关闭的消息
pw.println("finish");
}
System.out.println(str);
//在用输出流pw发送消息
pw.println("Server: "+str);
}
//4,在这用try,catch来包裹接收到客户端,端着个客户端socke(管道)关闭时,在这里来关闭服务的socket(管道)
}catch (SocketException e) { //这里可以在捕获一个socke异常,判断客户端socket是否是非法关闭
System.err.println("客户端关闭异常");
} catch (IOException e) {
e.printStackTrace();
}finally{
if(s!=null)s.close();
}
}
//
} catch (IOException e) {
e.printStackTrace();
}finally{
//当服务器停止时,关闭服务器
try {
if(ss!=null)ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端:
/*
* 客户端:
* 1,建立连接服务的socket(管道),需要本机ip地址和服务器的端口号
* 可以用InetAddress获取本机ip地址
* 2,两端的数据通信:getInputStream(),getOutputStream()可以获取Soket中的输入流和输出流,可以用
* 输入流和输出流来相互传送数据
* 3,关闭socket
*
* ★关闭的最佳方法:当客户端要关闭时,先给服务器发送一条要关闭,这时服务器在释放资源,释放完再给客户端传回
* 资源 释放完毕的消息,这是客户端接受到消息时在关闭连接socket(管道)。
* */
class TcpClient{
public static void main(String[] args) {
Socket s = null;
BufferedReader br = null;
PrintWriter pw = null;
//专门读取键盘输入的流
BufferedReader keyBr = null;
try {
//获取本机ip
InetAddress ipd = InetAddress.getLocalHost();
String ip = ipd.getHostAddress();
//1,连接服务器
s = new Socket(ip, 9999);
//2,绑定输入输出流
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw = new PrintWriter(s.getOutputStream(),true);//记得要多加个参数刷新
//我这里来读取键盘的输入发送给服务器,需要在创建一个输入流
//用的是字符流读取键盘输入,标准输入流失字节流,需要转换流
keyBr = new BufferedReader(new InputStreamReader(System.in));
String str = null;
while((str=keyBr.readLine())!=null){
//向服务器发送消息
pw.println(str);
//读取服务器的消息(其实这可用另一条线程来单独读取更好)
String strs = br.readLine();
//★最佳关闭方法
//接受到可以关闭消息是就break掉,退出循环
if(strs.trim().equals("finish")){
break;
}
System.out.println(strs);
}
}catch (SocketException e) { //服务器关闭异常
System.err.println("~~~~~~~~~~~服务器断开连接!!!!");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭socket
try {
if(s!=null)s.close();
} catch (IOException e) {
e.printStackTrace();
}
//注意的是这笔还要关闭keyBr,因为这个keyBr是读取键盘输入的流,没有跟socke绑定
//所以socke关闭时,这个流不会关闭,需要另外关闭
try {
if(keyBr!=null)keyBr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
udp
udp传送数据不可靠,会丢包(但速度快)
udp不用流接收和发送数据
栗子:服务器端:
/*
* 服务器端:
* 1,用DatagramSocket创建通道
* 2,两端的通信用:创建DatagramPacket数据接收包和发送包
* 3,用receive()方法接收包,send()发送包
* 4,关闭
* */
class UdpServer{
public static void main(String[] args) {
DatagramSocket ds = null;
try {
//1,创建连接端口
ds = new DatagramSocket(5858);
//2,创建接受送包,并将客户端的数据存放在bytr[]缓冲区中
byte[] buf = new byte[1024];
DatagramPacket receivrdp = new DatagramPacket(buf, buf.length);
//接收数据,用getData()获取缓冲区数据,返回的是byte[]
ds.receive(receivrdp);
String str = new String(receivrdp.getData(),0,receivrdp.getLength()); //将字符转换成字符串
System.out.println(str);
//3,创建发送包
//只能发送byte[]类型的数据,所以需要转换
SocketAddress ip = receivrdp.getSocketAddress();
String strs = "我是服务器!!!";
byte[] by = strs.getBytes();
DatagramPacket dp = new DatagramPacket(by, by.length,
ip);
//发送数据
ds.send(dp);
//
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭通道
if(ds!=null)ds.close();
}
}
}
客户端:
/*
* 客户端
* */
class UdpClien{
public static void main(String[] args) {
DatagramSocket ds = null;
try {
//1创建通道
ds = new DatagramSocket(6868);
//获取本机ip
InetAddress ipd = InetAddress.getLocalHost();
String ip = ipd.getHostAddress();
//2,创建发送包
//只能发送byte[]类型的数据,所以需要转换
String str = "hello";
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.getBytes().length,
new InetSocketAddress(ip, 5858));
//发送数据
ds.send(dp);
//3,创建接受送包,并将客户端的数据存放在bytr[]缓冲区中
byte[] buf = new byte[1024];
DatagramPacket receivrdp = new DatagramPacket(buf, buf.length);
//接收数据,用getData()获取缓冲区数据,返回的是byte[]
ds.receive(receivrdp);
String strs = new String(receivrdp.getData(),0,receivrdp.getLength()); //将字符转换成字符串
System.out.println(strs);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}