网络编程
网络通讯的三要素
IP 端口 传输协议
本机地址 127.0.0.1
网关: 交换机的地址
子网掩码:网段 255.255.255.0
传输协议分为 UDP 和TCP
UDP 64k 速度快 不用建立连接
InetAddress类
InetAddress ip = InetAddress.getLocalHost()
InetAddress ip = InetAddress.getByName(“192.168.133.12”); 获得ip对象
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Jih {
public static void main(String[] args) throws UnknownHostException {
InetAddress ip = InetAddress.getLocalHost();
System.out.println(ip.getHostAddress()); //Ip字符串
System.out.println(ip.getHostName());
}
}
UDP传输(了解) 以数据包的形式进行传输
DatagramSocket 建立底层连接
Datagrampacket(bs,bs.length,InetAddress.getByName(""),端口号)
dp.getAddress() 获得发送方的ip地址
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ChatRoomTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
pool.execute(new fuwuduan());
pool.execute(new kehuduan());
//线程池会有60s的延迟 当你执行完后 会60s后自动关闭
/*new Thread(new fuwuduan()).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new kehuduan()).start();*/
}
}
class kehuduan implements Runnable {
public void run() {
try {
DatagramSocket ds = new DatagramSocket();
Scanner sc = new Scanner(System.in);
InetAddress ip = InetAddress.getLocalHost();
// 将ip改成InetAddress.getbyname("192.168.133.255")
// 那么所有人都可以进行聊天了
String line;
System.out.println("开始聊天");
while ((line = sc.next()) != null) {
byte[] bs = line.getBytes();
ds.send(new DatagramPacket(bs, bs.length, ip, 8888));
if ("over".equals(line)) {
ds.close();
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class fuwuduan implements Runnable {
public void run() {
try {
DatagramSocket ds = new DatagramSocket(8888);
byte[] bs = new byte[1024 * 64];
DatagramPacket dp = new DatagramPacket(bs, 0, bs.length);
System.out.println("已开启服务");
while (true) {
ds.receive(dp);
String line = new String(dp.getData(), 0, dp.getLength());
System.out.println(line);
if ("over".equals(line)) {
break;
}
}
ds.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
TCP协议********* 以二进制流的形式进行传输
socket serverSocket
字符流特别容易卡住 需要加上 newline
缓冲输出流记得加上flush
bos.shutdownoutput() 将输出阻断后再进行输入
四个程序
1.客户端发送信息 收到没 服务端收到信息打印在屏幕上,并返回收到了
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class fuwu {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
System.out.println(br.readLine());
s.shutdownInput();
bw.write("收到了收到了");
bw.newLine();
bw.flush();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class kehu {
public static void main(String[] args) {
try {
Socket s = new Socket("localhost", 9999);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
bw.write("收到没");
bw.newLine();
bw.flush();
s.shutdownOutput();
System.out.println(br.readLine());
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.客户端一直能通过键盘发送数据,服务端收到信息打印在频幕上,输入over时两端都终止
public class test2 {
public static void main(String[] args) {
// 客户端一直能通过键盘发送数据,服务端收到信息打印在频幕上,输入over时两端都终止
new Thread(new Runnable() {
@Override
public void run() {
try {
ServerSocket ss = new ServerSocket(7777);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if ("over".equals(line)) {
break;
}
}
br.close();
s.close();
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Socket s = new Socket("localhost", 7777);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
Scanner sc = new Scanner(System.in);
String line;
while ((line = sc.next()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
if ("over".equals(line)) {
break;
}
}
bw.close();
bw.close();
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
3.客户端一直能通过键盘输入一串小写字母,服务端打印到频幕上并返回大写字母 一边写一边读用缓冲字符流
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class fuwu1 {
public static void main(String[] args) {
// 客户端一直能通过键盘输入一串小写字母,服务端打印到频幕上并返回大写字母 一边写一边读用缓冲字符流
new Thread() {
@Override
public void run() {
try {
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String str;
while ((str = br.readLine()) != null) {
System.out.println(str);
bw.write(str.toUpperCase());
bw.newLine();
bw.flush();
if ("over".equals(str)) {
s.close();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
try {
Socket s = new Socket("localhost", 9999);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
Scanner sc = new Scanner(System.in);
System.err.println("开始聊天吧");
String str;
while ((str = sc.next()) != null) {
bw.write(str);
bw.newLine();
bw.flush();
System.out.println(br.readLine());
if ("over".equals(str)) {
s.close();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
4.客户端向服务端发送一个图片
public class test2 {
public static void main(String[] args) {
// 客户端向服务端发送一个图片
new Thread() {
public void run() {
try {
Socket s = new Socket("localhost", 9999);
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:/300.jpg"));
byte[] bs = new byte[1024];
int len;
while ((len = bis.read(bs)) != -1) {
bos.write(bs, 0, len);
bos.flush();
}
bis.close();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
new Thread() {
public void run() {
try {
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept();
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/mmm.jpg"));
byte[] bs = new byte[1024];
int len;
while ((len = bis.read(bs)) != -1) {
bos.write(bs, 0, len);
bos.flush();
}
bis.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
}
5.多线程并发上传图片
多个客户端同时上传的问题,可以使用多线程
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TcpServer5 {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(9999);
// 想要能够接收多个客户端的请求,用while循环将建立连接
// 接受客户端的请求,s.close 但ss不能关;
while (true) {
// 每进来一次,就建立一次连接
// 但必须等待前一个执行完,下一个才能执行,
Socket s = ss.accept();
ExecutorService pool = Executors.newCachedThreadPool();
pool.execute(new UploadTask(s));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class UploadTask implements Runnable {
Socket s;
public UploadTask(Socket s) { // 传入一个socket对象
this.s = s;
}
@Override
public void run() {
try { // 获取输入流读取客户端传过来的数据
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("C:/hanyakun/韩亚昆大数据学习总结/java基础/" + System.nanoTime() + ".jpg"));
byte[] bs = new byte[1024];
int len;
while ((len = bis.read(bs)) != -1) {
bos.write(bs, 0, len);
}
bos.flush();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
public class TcpClient5 {
public static void main(String[] args) {
try {
for (int i = 0; i < 10; i++) {
Socket s = new Socket("localhost", 9999);
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("C:/hanyakun/韩亚昆大数据学习总结/java基础/mmm.jpg"));
byte[] bs = new byte[1024];
int len;
while ((len = bis.read(bs)) != -1) {
bos.write(bs, 0, len);
}
bos.flush();
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}