------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
●网络模型
OSI参考模型
TCP/IP参考模型
●网络通讯要素
IP地址
端口号
传输协议
●
(1)找到对方IP
(2)数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识,为了方便称呼这个数字,叫做端口,逻辑端口
(3)定义通信规则,这个通讯规则称为协议,国际组织定义了通用协议TCP/IP
●IP地址
InetAddress[] ia = InetAddress.getAllByName("www.baidu.com");
for (InetAddress inetAddress : ia) {
System.out.println(inetAddress.getHostName());
System.out.println(inetAddress.getHostAddress());
}
InetAddress i = InetAddress.getLocalHost();
System.out.println(i);
System.out.println(i.getHostName());
System.out.println(i.getHostAddress());
●端口号:
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024 系统使用或保留端口
●传输协议
通讯的规则
常见协议:TCP UDP
★UDP
将数据即源和目的封装成数据包中,不需要建立连接
每个数据包的大小在限制在64K内
因无连接,是不可靠协议
不需要建立连接,速度快
★TCP
建立连接,形成传输数据的通道
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
●Socket
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket之间通过IO传输
●UDP传输
DsatagramSocket与DatagramPacket
建立发送端,接收端
建立数据包
调用Socket的发送接收方法
关闭Socket
发送端与接收端是两个独立的运行程序
192.168.1.255 port 向192.168.1.x网段port端口所有机器发广播
UDP接收
DatagramSocket ds = new DatagramSocket(9900);
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println("ip:"+ip);
System.out.println("data:"+data);
System.out.println("port:"+port);
ds.close();
UDP发送
DatagramSocket ds = new DatagramSocket();
byte[] data = "udp ge menlai le".getBytes();
DatagramPacket dp = new DatagramPacket(data, data.length,InetAddress.getByName("192.168.161.1"), 10000);
ds.send(dp);
ds.close();
UDP聊天
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
class ChatSend1 implements Runnable{
privateDatagramSocket ds;
privatebyte[] buf;
Scannersc = new Scanner(System.in);
publicChatSend1(DatagramSocket ds) {
super();
this.ds= ds;
}
@Override
publicvoid run() {
while(true){
try{
buf = sc.next().getBytes();
DatagramPacketdp = newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.161.1"),10010);
ds.send(dp);
}catch (UnknownHostException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ChatRecieve1 implements Runnable{
privateDatagramSocket ds;
privateDatagramPacket dp;
private byte[] buf = new byte[1024];
publicChatRecieve1(DatagramSocket ds) {
super();
this.ds= ds;
}
@Override
publicvoid run() {
dp= new DatagramPacket(buf, buf.length);
while(true){
try{
ds.receive(dp);
Stringstring = new String(dp.getData(),0,dp.getLength());
System.out.println(string);
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class ChatDemo1 {
publicstatic void main(String[] args) throws SocketException {
DatagramSocketds= new DatagramSocket(10000);
ChatSend1chatSend = new ChatSend1(ds);
ChatRecieve1chatRecieve = new ChatRecieve1(ds);
Threadthread = new Thread(chatSend);
Threadthread2 = new Thread(chatRecieve);
thread.start();
thread2.start();
}
}
UDP图形化界面 聊天
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
class FrameInit{
public static TextArea ta;
private Frame frame;
private TextField tf ,tf1;
private Button btn;
private Button cls;
private DatagramPacket dp;
private DatagramSocket ds;
private byte[] buf;
private String msg = null;
public FrameInit(DatagramSocket ds) {
super();
this.ds = ds;
init();
}
public void init(){
frame = new Frame();
tf = new TextField(17);
tf1 = new TextField(27);
btn = new Button("发送");
cls = new Button("清空");
ta = new TextArea(25,60);
ta.setEditable(false);
tf.setText("192.168.161.1:8008");
frame.setBounds(200, 200, 500, 500);
frame.setTitle("Socket通信");
frame.setLayout(new FlowLayout());
frame.add(tf);
frame.add(tf1);
frame.add(btn);
frame.add(cls);
frame.add(ta);
MyEvevt();
frame.setVisible(true);
}
public void MyEvevt(){
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
if(tf1.getText().length()>0){
buf = tf1.getText().getBytes();
dp = new DatagramPacket(buf, buf.length,InetAddress.getByName(tf.getText().split(":")[0]),Integer.parseInt(tf.getText().split(":")[1]));
ds.send(dp);
ta.append("发送:\r\n"+tf1.getText()+"\r\n");
}else{
ta.setText("发送内容不能为空!"+"\r\n");
}
} catch (Exception e1) {
// TODO Auto-generatedcatch block
e1.printStackTrace();
}
}
});
cls.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ta.setText("");
}
});
}
}
public class SocketFrame {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(11000);
FrameInit frameInit = new FrameInit(ds);
byte[] b = new byte[1024];
while(true){
DatagramPacket dp = new DatagramPacket(b, b.length);
ds.receive(dp);
String string = new String(dp.getData(),0,dp.getLength());
FrameInit.ta.append("接收:");
FrameInit.ta.append(string+"\r\n");
}
}
}
●TCP传输
Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭Socket
同样,客户端与服务器端是两个独立的应用程序
因为tcp是面向连接的,所以在建立socket服务时,就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输
class TCPClient{
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.161.1",11000);
OutputStream os = s.getOutputStream();
os.write("tcp ge menlai le".getBytes());
s.close();
}
}
/*服务端:
* 1.建立服务端的socket服务,并监听一个端口
* 2.获取连接过来的客户端对象,通过ServerSocket的accept方法,所以这个方法时阻塞式的
* 3.客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据
*
*
* */
class TCPServer{
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket();
Socket s = ss.accept();
InputStream is = s.getInputStream();
byte[] buf = new byte[1024];
int len=0;
len = is.read(buf);
String string = new String(buf,0,len);
System.out.println(string);
}
}
●TCP客户端和服务端不带缓冲区
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
class TCPtextServer {
public static void main(String[] args) throws IOException {
ServerSocket ss =new ServerSocket(10010);
Socket accept = ss.accept();
InputStream is = accept.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
String string = new String(buf,0,len);
System.out.println(string);
OutputStream os = accept.getOutputStream();
os.write(string.toUpperCase().getBytes());
accept.close();
}
}
class TCPtextClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket(InetAddress.getLocalHost(), 10010);
OutputStream os = s.getOutputStream();
os.write("tcp serveri am coming!-----Client".getBytes());
InputStream is = s.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
String string = new String(buf,0,len);
System.out.println(string);
s.close();
}
}
●TCP客户端和服务端带缓冲区
public class TCPClientBuffer {
public static void main(String[] args) throws IOException {
Socket s = new Socket(InetAddress.getLocalHost(),10010);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader brin = new BufferedReader(new InputStreamReader(System.in));
BufferedReader bs = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=brin.readLine())!=null){
if("over".equals(line))
break;
System.out.println(line);
bw.write(line);
bw.newLine();
bw.flush();
line=bs.readLine();
System.out.println("Server:"+line);
}
s.close();
brin.close();
}
}
public class TCPServerBuffer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10010);
Socket s = ss.accept();
System.out.println("Client:-----connection");
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//BufferedWriter bw =new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=br.readLine())!=null){
System.out.println("Client"+line);
/*bw.write(line.toUpperCase());
bw.newLine();
bw.flush();*/
pw.println(line);
}
s.close();
ss.close();
}
}
●使用BufferedReader注意换行!!!!!!!!!!!!!!!!!!!!!!!
因为客户端和服务端都有阻塞式方法,这些方法没有读到结束标记,那么就一直等,而导致两端都在的等待
●TCP发送文件
客户端先发送结束标记给服务端
服务端在上传完成之后 返回 上传成功
此例为字节流传输
也可用字符流 或者 PrintWriter
结束标记用时间做标记 System.currentTimeMillis()
public class TCPClientBuffer {
public static void main(String[] args) throws IOException {
Socket s = new Socket(InetAddress.getLocalHost(),10010);
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("g:/tupian.jpg"));
byte[] buf = new byte[1024];
int len = 0;
while((len = bis.read(buf))!=-1){
bos.write(buf,0,len);
bos.flush();
}
bis.close();
s.close();
}
}
public class TCPServerBuffer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10010);
Socket s = ss.accept();
System.out.println("Client:-----connection");
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("g:/socket.jgp"));
int len = 0;
byte[] buf = new byte[1024];
while((len = bis.read(buf))!=-1){
bos.write(buf, 0, len);
bos.flush();
}
s.close();
ss.close();
bos.close();
}
}