还是直接上代码,什么TCP是面向连接的可靠传输,UDP是不可靠传输,还有TCP3次握手4次挥手等等等理论了解一下就好,知道怎么用才是比较实用的(大神们做底层的请不要批判我)
UDP 的使用范围相对于TCP很窄,而且编程比 TCP 难:
多数情况下是用TCP的,但在实时音视频聊天功能通常都会使用 UDP 实现, 还有一个应用就是翻墙了(这个看被人说的,有木有大神有这个项目源码啊?跪求)
TCP1:
import java.net.*;
import java.io.*;
public class TCPServer2 {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(6666);
while(true) {
//由于客户端请求会将客户端自己的ip和端口号传递给服务端(ip数据包中就有源ip地址和目的ip地址)
//所以服务端通过accept()返回的socket中就有客户端的ip和端口号
Socket socket = ss.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
String s = null;
if((s=dis.readUTF()) != null) {
System.out.println(s);
System.out.println(socket.getInetAddress());
System.out.println(socket.getPort());
}
dos.writeUTF("xiaohui");
// Writes a string to the underlying output stream using modified UTF-8 encoding in a machine- // independent manner.
dos.close();
dis.close();
socket.close();
}
}catch(IOException e) {
System.out.println("运行错误!");
e.printStackTrace();
}
}
}
import java.net.*;
import java.io.*;
public class TCPClient2 {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1",6666);
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF("shangshuai");
String s = null;
if((s=dis.readUTF()) != null) {
System.out.println(s);
}
dis.close();
dos.close();
socket.close();
}catch(IOException e) {
System.out.println("连接错误!");
e.printStackTrace();
}
}
}
TCP2:
import java.net.*;
import java.io.*;
public class TCPServer3 {
public static void main(String[] args) {
try{
ServerSocket ss = new ServerSocket(8888);
Socket socket = ss.accept();
BufferedReader fbr = new BufferedReader( //文件输入流
new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream()); //文件输出流(PrintWriter 参数为OutPrintStream)
System.out.println("client:"+fbr.readLine());
BufferedReader kbw = new BufferedReader( //键盘输入流
new InputStreamReader(System.in)); //??????????????????????
String s = kbw.readLine();
while(!s.equals("over")) {
pw.println(s);
pw.flush(); //初次编写忘了,往外送的都应该清空一下
System.out.println("server:"+s);
System.out.println("client:"+fbr.readLine());
s = kbw.readLine();
}
fbr.close();
pw.close();
kbw.close();
socket.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
import java.net.*;
import java.io.*;
public class TCPClient3 {
public static void main(String[] args) {
try{
Socket socket = new Socket("127.0.0.1",8888);
BufferedReader fbr = new BufferedReader( //文件输入流
new InputStreamReader(socket.getInputStream()));
BufferedReader kbr = new BufferedReader(new InputStreamReader(System.in)); //键盘输入流,阻塞式
PrintStream ps = new PrintStream(socket.getOutputStream()); //文件输出流
String s = kbr.readLine();
while(!s.equals("over")) {
ps.println(s);
//println() 是PrintStream中的。在DataOutputStream中用的是Write() 方法
ps.flush(); //往外送信息都要清空一下
System.out.println("Client:"+s);
System.out.println("Server:"+fbr.readLine());
s = kbr.readLine();
}
fbr.close();
kbr.close();
ps.close();
socket.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
TCP3:
import java.net.*;
import java.io.*;
public class TCPServer {
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(6666); //
while(true) {
Socket s = ss.accept(); //为了一直能接受多个Client的连接,所以用循环
//这是接受Client端的连接请求。返回类型为stock。(在Server端建立一个stock与client端的stock进行通信)
System.out.println("a client connect!");
DataInputStream ais = new DataInputStream(s.getInputStream());
System.out.println( ais.readUTF() );
//readUTF()是阻塞式的,只有接收到传来的信息才往下运行.(未接收到信息则while循环无法进行,就无法接受其他client)
ais.close(); //关闭流
s.close(); //关闭socket端口
}
}
}
import java.net.*;
import java.io.*;
public class TCPClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket("127.0.0.1",6666);
//127.0.0.1是回送地址,是自己机器上的地址。到这句就可以完成连接了
OutputStream os = s.getOutputStream(); //传送数据用到流(用到Socket类中的getOutputStream()方法)
DataOutputStream dos = new DataOutputStream(os);
Thread.sleep(10000); //为什么要睡眠?
dos.writeUTF("hello "); //按unicode 8传输内容
dos.flush(); //flush()只在OutputStream类中有,将缓存中的内容清空到指定文件
dos.close();
s.close(); //关闭socket端口
}
}
UDP:
import java.net.*;
public class UDPServer {
public static void main(String[] args) throws Exception {
byte buf[] = new byte[1024]; //这里竟然写成了Byte(这是类)
//Buf是接受数据的容器。
DatagramPacket dp = new DatagramPacket(buf,buf.length);
DatagramSocket ds = new DatagramSocket(8888);
//DatagramSocket 是插座,但插座是无线连接的(不用先连通道再发信息)
while(true) {
ds.receive(dp);
//Receive( )也是阻塞式的
System.out.println(new String(buf,0,dp.getLength())); //得到的是dp包中拥有数据的实际长度
}
}
}
//可以看出UDP的Severe端像一个网兜开着等着Client端往这边发信息
import java.net.*;
public class UDPClient {
public static void main(String[] args) throws Exception {
byte[] buf = (new String("shangshuai").getBytes()); //竟然写成了getByte( )
//GetBytes( )将字符串解析成字节数组返回。
DatagramPacket dp = new DatagramPacket(buf,buf.length,
new InetSocketAddress("127.0.0.1",8888));
//UDP本身没有连接,包裹扔出去了要让他又去向,于是在包裹上标记IP地址和端口号
//InetSocketAddress继承自SocketAddress
DatagramSocket ds = new DatagramSocket(9999);
//Client端本身占据9999这个端口,向5678发送信息
ds.send(dp); //竟然漏了传送包
ds.close(); //关闭Client自身的端口
}
}