---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
TCP/IP参考模型
应用层、传输层、网络层、链路层
UDP总结:
1、将数据源和目的地封装到数据包中,不需要建立连接
2、每个数据包的大小限制在64k以内
3、因无连接。是不可靠协议
4、不需要建立连接。速度快
UDP发送端:
package com.xiaozhi.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendClient {
public static void main(String[] args) throws Exception {
//通过DatagramSocket建立udp服务
DatagramSocket datagramSocket=new DatagramSocket();
//确定数据并封装成数据包
byte[]bs="黑马我来了".getBytes();
DatagramPacket datagramPacket=new DatagramPacket(bs, bs.length,InetAddress.getByName("121.251.158.251"),10000);
//发送数据
datagramSocket.send(datagramPacket);
//关闭资源
datagramSocket.close();
}
}
UDP接受端:
package com.xiaozhi.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReviewClient {
public static void main(String[] args) throws Exception {
//通过DatagramSocket建立udp服务,可以指定端口号,也可以不指定
DatagramSocket datagramSocket=new DatagramSocket(10000);
//定义数据包,用于存储数据
byte[]bs=new byte[1024];
DatagramPacket datagramPacket=new DatagramPacket(bs, bs.length);
//接受数据,receive是阻塞式方法
while(true){
datagramSocket.receive(datagramPacket);
System.out.println(new String(datagramPacket.getData()));
}
// datagramSocket.close();
}
}
TCP的总结:
1、建立连接,形成传输数据的通道
2、在连接中进行大量数据的传输
3、通过三次握手完成连接、是可靠协议
4、必须建立连接。效率稍低
使用TCP协议写一个可以上传文件的服务器和客户端:
客户端步骤:
1、首先创建客户端的Socket服务,指定目的主机和端口号
2、得到上传文件的输入流
3、得到Socket的输出流
4、关闭流、关闭Socket
服务端步骤:
1、创建服务器端的ServerSocket服务,并指定端口号
2、通过accept接受客户端Socket对象
3、通过多线程技术,将每一个接受到的客户端Socket对象封装进一个线程中。
4、在run方法中得到保存文件的输出流、Socket的输入流
5、关闭流、关闭Socket
TCP上传客户端代码:
package com.xiaozhi.jingtian.tcp;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class UploadClient {
public static void main(String[] args) throws Exception, IOException {
//创建客户端的Socket服务,指定目的主机和端口号
Socket socket=new Socket("121.251.158.251",10000);
FileInputStream fileInputStream=new FileInputStream("c://1.bmp");
OutputStream outputStream=socket.getOutputStream();
byte[]buffer=new byte[1024];
int lang = 0;
while((lang=fileInputStream.read(buffer))!=-1){
outputStream.write(buffer, 0, lang);
}
fileInputStream.close();
outputStream.close();
socket.close();
}
}
TCP上传服务器端代码:
package com.xiaozhi.jingtian.tcp;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.xml.crypto.Data;
public class UploadServer {
public static void main(String[] args) throws Exception {
//创建服务端的Socket服务,指定端口号
ServerSocket serverSocket=new ServerSocket(10000);
while(true){
//通过accept方法获取连接过来的Socket对象
Socket socket=serverSocket.accept();
new MyThread(socket).start();
}
}
}
class MyThread extends Thread{
private Socket socket;
public MyThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
System.out.println(socket.getInetAddress().getHostAddress()+"上传文件");
FileOutputStream fileOutputStream=new FileOutputStream("c://"+System.currentTimeMillis()+".bmp");
InputStream inputStream=socket.getInputStream();
byte[]buffer=new byte[1024];
int lang = 0;
while((lang=inputStream.read(buffer))!=-1){
fileOutputStream.write(buffer, 0, lang);
}
fileOutputStream.close();
inputStream.close();
socket.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
另外需要注意:
如果上传的文件是文本文件,可以使用缓冲流来上传,提高效率。
但是是BufferedReader的readLIne()方法判断的是每行是否有换行符。所以客户端发送数据的时候需要加换行。
也可以使用PrintWriter,PrintWriter更方便一下,既可以设置autoFlush 的参数为true,自动刷新。又可以使用println方法,自带换行符,甚是方便。
下面是使用缓冲流优化的客户端,服务器端代码:
package com.xiaozhi.jingtian.tcp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class UploadClient {
public static void main(String[] args) throws Exception, IOException {
//创建客户端的Socket服务,指定目的主机和端口号
Socket socket=new Socket("121.251.158.251",10000);
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream("c://1.txt")));
BufferedWriter bufferedWriter= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String line=null;
while((line=bufferedReader.readLine())!=null){
bufferedWriter.write(line);
bufferedWriter.newLine();
bufferedWriter.flush();
}
bufferedReader.close();
bufferedWriter.close();
socket.close();
}
}
package com.xiaozhi.jingtian.tcp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.xml.crypto.Data;
public class UploadServer {
public static void main(String[] args) throws Exception {
//创建服务端的Socket服务,指定端口号
ServerSocket serverSocket=new ServerSocket(10000);
while(true){
//通过accept方法获取连接过来的Socket对象
Socket socket=serverSocket.accept();
new MyThread(socket).start();
}
}
}
class MyThread extends Thread{
private Socket socket;
public MyThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
System.out.println(socket.getInetAddress().getHostAddress()+"上传文件");
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c://"+System.currentTimeMillis()+".txt")));
String line=null;
while((line=bufferedReader.readLine())!=null){
bufferedWriter.write(line);
bufferedWriter.newLine();
bufferedWriter.flush();
}
bufferedReader.close();
bufferedWriter.close();
socket.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
下面是使用PrintWriter优化的客户端、服务端代码
package com.xiaozhi.jingtian.tcp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class UploadClient {
public static void main(String[] args) throws Exception, IOException {
//创建客户端的Socket服务,指定目的主机和端口号
Socket socket=new Socket("121.251.158.251",10000);
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream("c://1.txt")));
PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);
String line=null;
while((line=bufferedReader.readLine())!=null){
printWriter.println(line);
}
bufferedReader.close();
printWriter.close();
socket.close();
}
}
package com.xiaozhi.jingtian.tcp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.xml.crypto.Data;
public class UploadServer {
public static void main(String[] args) throws Exception {
//创建服务端的Socket服务,指定端口号
ServerSocket serverSocket=new ServerSocket(10000);
while(true){
//通过accept方法获取连接过来的Socket对象
Socket socket=serverSocket.accept();
new MyThread(socket).start();
}
}
}
class MyThread extends Thread{
private Socket socket;
public MyThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
System.out.println(socket.getInetAddress().getHostAddress()+"上传文件");
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter printWriter =new PrintWriter(new FileOutputStream("c://"+System.currentTimeMillis()+".txt"),true);
String line=null;
while((line=bufferedReader.readLine())!=null){
printWriter.println(line);
}
bufferedReader.close();
printWriter.close();
socket.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
shutdownOutput方法的作用:
关闭客户端的输出流。相当于给流中加入一个结束标记-1。
也可以这样理解s.shutdownOutput();关闭的是客户端的输出流,同时服务器端的输入流也随之关闭。
s.shutdownIntput();也是同样的道理,关闭客户端的输入流,同时服务器端的输出流也随之关闭。
---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------