网络协议分层
TCP三次握手
IP解决了每个电脑唯一的一个ID的问题
TCP传输比较可靠,需要建立连接,确保数据送达,但是速度较慢
UDP传输不可靠,不需要建立连接,只需要发送,速度快
一、TCP
分为服务器端和客户端,要先建立连接
服务器端new一个ServerSocket,指定好端口
然后accpet客户端
服务器端:
package netSocket;
import java.net.*;
import java.io.*;
public class TCPServer {//服务器端
public static void main(String[] args) {
InputStream in = null;
OutputStream out = null;
try{
ServerSocket ss = new ServerSocket(5888);
Socket socket = ss.accept();//接收到返回的是Scoket类
in = socket.getInputStream();
out = socket.getOutputStream();
DataInputStream dis = new DataInputStream(in);
DataOutputStream dos = new DataOutputStream(out);
String s = null;
if( (s = dis.readUTF() ) != null ) {//读客户端的数据
System.out.println(s);
System.out.println("from:"+ socket.getInetAddress() );//获得客户端的IP
System.out.print("Port:" + socket.getPort() );//获得端口
}
dos.writeUTF("hi, hello");
dis.close();
dos.close();
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
客户端:
new的时候指定好IP地址和端口
package netSocket;
import java.io.*;
import java.net.*;
public class TCPclient {
public static void main(String[] args) throws Exception{
InputStream is = null;
OutputStream os = null;
try{
Socket socket = new Socket("localhost", 5888);
is = socket.getInputStream();
os = socket.getOutputStream();
DataInputStream dis = new DataInputStream(is);
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("hello! Several!");
String s = null;
if( (s = dis.readUTF() ) != null);
System.out.println(s);
dos.close();
dis.close();
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
用TCP实现单次聊天
客户端
package netSocket;
import java.io.*;
import java.net.*;
public class TalkClient {
public static void main(String[] args){
try{
Socket socket = new Socket("127.0.0.1",8888);
BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()) );//从服务器读
PrintWriter pw = new PrintWriter(socket.getOutputStream());//向服务器输出
BufferedReader sin = new BufferedReader(new InputStreamReader( System.in) );
String readline = null;
readline = sin.readLine();
while( ! readline.equals("exit") ){
pw.println(readline);
pw.flush();
System.out.println("client: "+ readline);
System.out.println("Server: "+ br.readLine() );
readline = sin.readLine();
}
br.close();
pw.close();
sin.close();
socket.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
服务器端
package netSocket;
import java.net.*;
import java.io.*;
public class TalkServer {
public static void main(String[] args){
try{
ServerSocket servel = new ServerSocket(8888);
Socket socket = servel.accept();
BufferedReader br = new BufferedReader(new InputStreamReader( socket.getInputStream()) );//读客户端
PrintWriter pw = new PrintWriter( socket.getOutputStream() );//往客户端写
BufferedReader sin = new BufferedReader( new InputStreamReader(System.in) );//读键盘
String line = null;
System.out.println("client"+ br.readLine());//从客户端读一句话
line = sin.readLine();
while( !line.equals("exit") ){
pw.println(line);//把服务器的话写到服务端
pw.flush();
System.out.println("Server: "+ line);
System.out.println("client: "+ br.readLine());
line = sin.readLine();
}
br.close();
pw.close();
socket.close();
servel.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
UDP
UDP不需要建立连接
传输通过包来传输:DatagramPacket
然后DatagramSocket设置端口
经常用字节数组来存储数据
服务器端
package netSocket;
import java.net.*;
import java.io.*;
public class UDPServer {
public static void main(String[] args) throws Exception{
byte buf[] = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);//包
DatagramSocket ds = new DatagramSocket(5678);//端口
while(true){
ds.receive(dp);//接收到字节数组中
ByteArrayInputStream bais = new ByteArrayInputStream(buf);//从字节数组中读东西
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readLong());
}
}
}
客户端
package netSocket;
import java.io.*;
import java.net.*;
public class UDPClient {
public static void main(String[] args){
long n = 10000L;
ByteArrayOutputStream baos = new ByteArrayOutputStream();//用字节输出流
DataOutputStream dos = new DataOutputStream(baos);
try{dos.writeLong(n);//把long写入字节数组
}catch(IOException e){
System.out.println("IOEx");
}
byte[] buf = baos.toByteArray();//转化为字节数组
DatagramPacket dp = new DatagramPacket(buf, buf.length,//UDP要打包传输
new InetSocketAddress("127.0.0.1",5678) );//要传输的IP地址和端口地址
try{DatagramSocket ds = new DatagramSocket(9999);//设置客户端的端口
ds.send(dp);//发送包
ds.close();
}catch(Exception e){
e.printStackTrace();
}
}
}