一、网络编程
网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一个设备反馈的数据。
目的:传播交流信息、数据交换、通信
二、网络通信的要素
IP和端口号
- 网络通信的协议
三、TCP实现聊天
- 客户端
1.连接服务器
2.发送消息
//客户端
public class TcpClient {
public static void main(String[] args) {
Socket socket =null;
OutputStream outputStream =null;
//需要知道服务器的地址
try {
//ip和端口号
InetAddress serverIp = InetAddress.getByName( "127.0.0.1" );
int port=8888;
//创建socket连接
socket = new Socket(serverIp,port);
//发送消息IO流
outputStream = socket.getOutputStream();
outputStream.write( "正在学习网络编程".getBytes() );
} catch (Exception e) {
e.printStackTrace();
}finally {
if (outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 服务器
1.建立服务的端口 ServerSocket
2.等待用户的链接 accept
3.接受用户的消息
//服务器
public class TcpServer1 {
public static void main(String[] args) {
ServerSocket socket = null;
InputStream inputStream = null;
ByteArrayOutputStream baos = null;
Socket accept = null;
//地址
try {
socket = new ServerSocket(8888);
//等待客户端连接
accept = socket.accept();
//读取客户端的消息
inputStream = accept.getInputStream();
//管道流
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len= inputStream.read(buffer))!=-1){
baos.write( buffer,0,len );
}
System.out.println(baos.toByteArray());
baos.close();
inputStream.close();
accept.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if (baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (accept!=null){
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
四、TCP实现文件上传
客户端
//客户端
public class TcpClient2 {
public static void main(String[] args) throws IOException {
//创建一个Socket连接
Socket socket = new Socket( InetAddress.getByName( "127.0.0.1" ),8888);
//创建一个输出流
OutputStream os = socket.getOutputStream();
//文件流,读取文件
FileInputStream fis = new FileInputStream( new File( "24134.jpg" ) );
//写出文件
byte[] buffer = new byte[1024];
int len;
while ((len=fis.read(buffer))!=-1){
os.write( buffer,0,len );
}
//通知服务器传输完毕
socket.shutdownOutput();//已经传输完了
//确定服务器端接收完毕,才断开连接
InputStream inputStream = socket.getInputStream();
//String byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bt = new byte[1024];
int len1;
while ((len1=inputStream.read(bt))!=-1){
baos.write( bt,0,len1 );
}
System.out.println( baos.toByteArray() );
//关闭资源
fis.close();
os.close();
socket.close();
}
}
服务端
//服务器
public class TcpServer2 {
public static void main(String[] args) throws IOException {
//创建服务
ServerSocket serverSocket = new ServerSocket(8888);
//监听客户端的连接
Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//获取文件输入流
InputStream is = socket.getInputStream();
//文件输出
FileOutputStream fos = new FileOutputStream( new File( "receive" ) );
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write( buffer,0,len );
}
//通知客户端接收完毕
OutputStream os = socket.getOutputStream();
os.write( "接收完毕".getBytes());
//关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
五、UDP发送消息
发送端
//不需要连接服务器
public class UdpClient1 {
public static void main(String[] args) throws IOException {
//建立一个Socket
DatagramSocket socket = new DatagramSocket();
//建个包
String xx = "你好啊,UDP";
//发送给谁
InetAddress localhost = InetAddress.getByName( "localhost" );
int port=8888;
//数据,数据的长度,要发送给谁
DatagramPacket packet = new DatagramPacket( xx.getBytes(), 0, xx.getBytes().length, localhost, port );
//发送包
socket.send( packet );
//关闭流
socket.close();
}
}
接收端
public class UdpServer1 {
public static void main(String[] args) throws IOException {
//开放端口
DatagramSocket socket = new DatagramSocket(8888);
//接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket( buffer, 0, buffer.length );
socket.receive( packet );//阻塞接收
System.out.println(packet.getAddress().getHostAddress());
System.out.println(packet.getData());
//关闭连接
socket.close();
}
}
六、UDP实现聊天
发送端
public class UdpSender1 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(8888);
//准备数据:控制台读取
BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) );
while (true){
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress( "localhost",6666 ) );
socket.send( packet );
if (packet.equals( "bye" )){
break;
}
}
socket.close();
}
}
接收端
public class UdpReceive2 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket( 6666 );
while (true){
//准备接收数据
byte[] bt = new byte[1024];
DatagramPacket packet = new DatagramPacket(bt,0,bt.length);
socket.receive( packet );//阻塞式接收数据
//断开连接
java.lang.String data = packet.getData().toString();
System.out.println(data);
if (data.equals( "bye" )){
break;
}
}
socket.close();
}
}
七、UDP多线程实现聊天功能
TalkSend类
public class TalkSend implements Runnable{
DatagramSocket socket =null;
BufferedReader reader =null;
private int fromPort;
private String toIP;
private int toPort;
public TalkSend(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
socket = new DatagramSocket( fromPort );
//读取数据
reader = new BufferedReader( new InputStreamReader( System.in ) );
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress( this.toIP,this.toPort ) );
socket.send( packet );
if (packet.equals( "bye" )){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
TalkReceive类
public class TalkReceive implements Runnable{
DatagramSocket socket =null;
private int port;
private String name;
public TalkReceive(int port,String name) {
this.port = port;
this.name = name;
try {
socket = new DatagramSocket( port );
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
//准备接收数据
byte[] bt = new byte[1024];
DatagramPacket packet = new DatagramPacket(bt,0,bt.length);
socket.receive( packet );//阻塞式接收数据
//断开连接
String data = packet.getData().toString();
System.out.println(name+":"+data.toString());
if (data.equals( "bye" )){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
TalkStudent类
public class TalkStudent {
public static void main(String[] args) {
//开启两个线程
new Thread(new TalkSend( 7777,"localhost",9999 )).start();
new Thread(new TalkReceive( 8888,"老师" )).start();
}
}
TalkTeacher类
public class TalkTeacher {
public static void main(String[] args) {
//开启两个线程
new Thread(new TalkSend( 5555,"localhost",8888 )).start();
new Thread(new TalkReceive( 9999,"学生" )).start();
}
}