网络编程的个人部分总结:
网络编程:
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。(1)网络编程三要素之IP:
每台电脑在网络中的独立的地址,我们在网络中传输数据就用这个地址。 IPv4,4个字节组成,4个0-255。IPv6m,8组,每组4个16进制。
ipconfig:查看本机IP192.168.12.42
ping:测试连接192.168.40.62
(2)网络编程三要素之端口号:
每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。
端口号范围从0-65535
编写网络应用就需要绑定一个端口号,尽量使用1024以上的,1024以下的基本上都被系统程序占用了。
常用端口
* mysql: 3306
* oracle: 1521
* web: 80
* tomcat: 8080
* QQ: 4000
(2)网络编程三要素之协议:为网络数据传输而建立的规则,标准。
TCP:面向连接(三次握手),传输速率略低,数据安全,分客户端和服务端。
UDP:面向无连接,传输速率高,速度快,不分客户端和服务端。
二:上代码
UDP多线程传输。
package Socket;
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;
public class Demo1_moreThread {
public static void main(String[] args) throws InterruptedException {
new Thread(new one()).start();
Thread.sleep(1000);
new two().start();
}
}
class one extends Thread {
@Override
public void run() {
try {
Scanner input = new Scanner(System.in);
DatagramSocket send = new DatagramSocket();// 通过DatagramSocket发送数据
while (true) {
String str = input.nextLine();
if (str.equals("1")) {
break;
}
DatagramPacket packet = new DatagramPacket(str.getBytes(), str.length(), InetAddress.getLocalHost(),
6667); // 指定要发送的数据,数据的长度,发给谁(ip和端口号)
send.send(packet);// 发送数据
}
send.close(); // 关闭码头
super.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class two extends Thread {
@Override
public void run() {
super.run();
try {
// 创建socket相当于创建码头 接收数据 指定端口号
// 创建package相当于创建集装箱
DatagramSocket socket = new DatagramSocket(6667);
DatagramPacket receiver = new DatagramPacket(new byte[1024], 1024);
while (true) {
socket.receive(receiver);// 接收货物
byte[] s = receiver.getData(); // 接收数据
int length = receiver.getLength(); // 获取有效的字节长度
System.out.println(new String(s, 0, length));// 打印通过控制台输入的字符串
String ip = receiver.getAddress().getHostAddress();
String port = receiver.getPort() + "";// 获取端口号和ip
// socket.close(); 一直接收就先不关闭了
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
打印:接下来看一个聊天demo(UDP传输),里面有些GUI的知识,不要求掌握的,大家都知道java做的界面很low.........为了让很多人看明白,写了大量注释。
/**
*
*/
package Socket;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
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.text.SimpleDateFormat;
import java.util.Date;
/**
* @author xiaoning
*
*/
public class Demo_GUIchat extends Frame {
private Button send;
private TextArea sendText;
private TextArea view;
private TextField textip;
private DatagramSocket socket;// 发送数据的socket
private BufferedWriter writer;
private Button log;
private Button clear;
private Button shake;
/**
* 初始化操作
*/
public Demo_GUIchat() {
init();
setsourth();
setCenter();
event();
}
/**
* 事件处理
*/
private void event() {
// 关闭窗口
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
try {
writer.close();
} catch (IOException e1) {
e1.printStackTrace();
}
socket.close();
System.exit(0);
}
});
// 发送数据
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
send();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
// 查看聊天记录
log.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
logFile();
}
});
// 清除聊天记录
clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
view.setText(""); // 清除聊天记录
}
});
// 震动
shake.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
send(new byte[] { -1 }, textip.getText());
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
// 按空格键发送聊天信息
sendText.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
try {
send();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
});
}
protected void shake() {
int x = this.getLocation().x;
int y = this.getLocation().y;
for (int i = 0; i < 20; i++) {
try {
this.setLocation(x + 20, y + 20);
this.setLocation(x + 20, y - 20);
this.setLocation(x - 20, y + 20);
this.setLocation(x - 20, y - 20);
this.setLocation(x, y);
Thread.sleep(20);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected void logFile() {
try {
writer.flush();// 刷新缓冲区
FileInputStream fis = new FileInputStream("config.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] b = new byte[7888];
while ((len = fis.read(b)) > 0) {
baos.write(b, 0, len);
}
String str = baos.toString();
view.setText(str);
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
protected void send(byte[] b, String ip) {
try {
// 发送数据 参数的含义就是让 震动的时候聊天记录页面不显示内容,
DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByName(ip), 6668);
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void send() throws Exception {
String text = sendText.getText();// 获取发送文本
String ip = textip.getText();
send(text.getBytes(), ip); // 255.255.255.255所有人
String time = getTime();
String str2 = time + "\r 我对:" + ip + "说:\r\n" + text + "\r\n\r\n";
view.append(str2); // 显示聊天的内容
sendText.setText("");// 发送文本区域清空
writer.write(str2);// 写入文本文档 //应该写入数据库
}
/**
* 获取当前的时间
*
* @return
*/
private String getTime() {
Date d = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
return format.format(d);
}
private void setCenter() {
Panel center = new Panel();
view = new TextArea();
sendText = new TextArea(5, 1);// 发送区域
center.setLayout(new BorderLayout());
center.add(sendText, BorderLayout.SOUTH);
center.add(view, BorderLayout.CENTER);// 聊天信息区域
view.setEditable(false);// 显示的聊天信息不可编辑
view.setFont(new Font("xxx", Font.PLAIN, 15));// 设置字体的样式
center.setFont(new Font("xxx", Font.PLAIN, 15));
view.setBackground(Color.WHITE);
this.add(center, BorderLayout.CENTER);
}
private void setsourth() {
Panel south = new Panel(); // 装按钮的
textip = new TextField(15);// 列 创建文本存储ip
textip.setText("127.0.0.1");// 默认跟谁聊天(ip)
send = new Button("发送");
clear = new Button("清屏");
log = new Button("记录");
shake = new Button("震动");
south.add(textip);// 添加按钮
south.add(send);
south.add(clear);
south.add(log);
south.add(shake);
this.add(south, BorderLayout.SOUTH);// 边框布局 指定panel位置
}
private void init() {
this.setLocation(500, 50); // 设置窗口位置
new Receive().start(); // 接收数据
try {
socket = new DatagramSocket();
writer = new BufferedWriter(new FileWriter("config.txt", true));// true的目的:每一次都追加聊天记录
// 而不是清空掉
} catch (Exception e) {
e.printStackTrace();
}
this.setSize(400, 500);// 设置大小
this.setVisible(true);
}
class Receive extends Thread {
public void run() {
try {
DatagramSocket receiver = new DatagramSocket(6668);
DatagramPacket packet = new DatagramPacket(new byte[7888], 7888);
while (true) {
receiver.receive(packet);
byte[] str = packet.getData();
int len = packet.getLength();
if (str[0] == -1 && len == 1) {// 如果发过来的数组第一个储存的位置是-1 并且长度是1
// 说明1发过来的是震动,不需要回复消息
shake(); // 调用震动
continue;
}
String s = new String(str, 0, len);
String time = getTime();
String ip = packet.getAddress().getHostAddress();
String strs = time + " " + ip + "对我说:\r\n" + s + "\r\n\r\n";
view.append(strs);
writer.write(strs);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}
/**
* @param args
*/
public static void main(String[] args) {
new Demo_GUIchat();
}
}