网络编程入门
什么是网络编程?
网络协议的分成:
UDP和TCP传输协议有什么区别?
//服务端程序
public class Receive {
public static void main(String[] ages) throws Exception{
//创建一个接瘦套接字
DatagramSocket ds=new DatagramSocket(11111);
while(true){
//定义一个接受原数据的byte数组
byte[] bt=new byte[1024];
//创建一个用于才数据包的对象
DatagramPacket dp=new DatagramPacket(bt,bt.length);
//接受发送端发送过来的数据包放到创建好的数据包对象中
ds.receive(dp);
//将原数据从数据包中取出
String line=new String(dp.getData(),0,dp.getLength());
//大印数据
System.out.println(line);
}
}
}
//客户端程序
public class Send {
public static void main(String[] ages) throws Exception{
//创建一个客户端的套接字
DatagramSocket ds=new DatagramSocket();
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//循环如果有数据就想服务端发送
while((line=br.readLine())!=null){
//获取原数据的byte数组类型
byte[] bt=line.getBytes();
//将原数据的byte数组用DatagramPacket对象来打包
DatagramPacket dp=new DatagramPacket(bt,bt.length,InetAddress.getByName("127.0.0.1"),11111);
ds.send(dp);
//判断如果用户输入 bay 结束客户端程序
if(line.equals("bay")){
break;
}
}
//关闭客户端程序
ds.close();
}
}
import java.net.*;
import java.io.*;
public class Udp2 {
private String TIP;
public static void main(String[] ages) throws Exception {
// 接受线程
new Thread(new Runnable() {
//创建服务套接字
DatagramSocket receive = new DatagramSocket(2005);
public void run() {
try {
Udp2 tudp=new Udp2();
while (true) {
byte[] bt = new byte[1024];
//用于拆解数据的包
DatagramPacket dp = new DatagramPacket(bt, bt.length);
//阻塞式接受数据
receive.receive(dp);
String line = new String(dp.getData(), 0, dp
.getLength());
//获取客户主机地址
String address=dp.getAddress().toString();
//输出信息
System.out.println(address + "说: " + line);
tudp.TIP=address;
}
} catch (Exception e) {
throw new RuntimeException("接受失败");
}finally{
receive.close();
}
}
}).start();
// 发送线程
new Thread(new Runnable() {
//创建客户端套接字
DatagramSocket send = new DatagramSocket();
public void run() {
try {
System.out.println("请输入对方的IP...(如直接回复请先按下回车键!)");
//获取用户输入要连接的IP
BufferedReader brIP=new BufferedReader(new InputStreamReader(System.in));
Udp2 tudp=new Udp2();
String ip;
if((ip=brIP.readLine())!=null){
tudp.TIP = ip;
}
System.out.println("可以开始聊天!");
//获取用户输入的聊天信息
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null) {
byte[] bt = line.getBytes();
//将数据打包
DatagramPacket dp = new DatagramPacket(bt, bt.length,
InetAddress.getByName(tudp.TIP),2004);
//发送
send.send(dp);
}
} catch (IOException e) {
throw new RuntimeException("数据发送失败");
}finally{
send.close();
}
}
}).start();
}
}
通过修改后的以上程序就可以实现了即可接受信息又可发送信息的程序,也就是一个完整的基于UDP的聊天程序了。
import java.net.*;
import java.io.*;
public class TcpImage {
public static void main(String[] ages) {
// 客户端
new Thread(new Runnable() {
//创建服务端套接字
Socket sk = null;
//定义文件读取流
FileInputStream fis = null;
public void run() {
try {
sk = new Socket(InetAddress.getByName("192.168.16.41"),
2008);
OutputStream os = sk.getOutputStream();
//将服务获取的读取流转换成字符流
BufferedReader bisr = new BufferedReader(
new InputStreamReader(sk.getInputStream()));
//获取原文件的读取流
fis = new FileInputStream("E:\\Images\\1.jpg");
byte[] bt = new byte[1024];
int end;
while ((end = fis.read(bt)) != -1) {
os.write(bt, 0, end);
}
//关闭客服端的写入流 这不非常重要 如果没有关闭该流 则数据不会发送到服务端
sk.shutdownOutput();
String line;
while ((line = bisr.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
throw new RuntimeException("客户端异常退出");
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException("客户端服务关闭异常");
}
}
if (sk != null) {
try {
sk.close();
} catch (IOException e) {
throw new RuntimeException("客户端服务关闭异常");
}
}
}
}
}).start();
// 服务端
new Thread(new Runnable() {
//创建一个服务套接字
ServerSocket ssk = null;
FileOutputStream fos = null;
public void run() {
try {
ssk = new ServerSocket(2002);
fos = new FileOutputStream("F:\\1_copy.jpg");
//获取服务端接受到的客户套接字
Socket sk = ssk.accept();
//获取客户套接字的读取流对象
InputStream br = sk.getInputStream();
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(sk.getOutputStream()));
byte[] bt = new byte[1024];
int endr;
while ((endr = br.read(bt)) != -1) {
fos.write(bt, 0, endr);
}
bw.write(sk.getInetAddress()+"成功上传");
bw.newLine();
bw.flush();
//关闭服务端接受的客户端套接字的写入流 这个步骤也非常重要 如果没有该步 那么服务端线程将处于线程等待机制
sk.shutdownOutput();
} catch (IOException e) {
throw new RuntimeException("服务端异常退出");
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException("服务写入流关闭异常");
}
}
if (ssk != null) {
try {
ssk.close();
} catch (IOException e) {
throw new RuntimeException("服务关闭异常");
}
}
}
}
}).start();
}
}