java基础,
分享于 点击 12664 次 点评:124
java基础,
网络编程概述
网络模型
IP地址
一、代码
InetAddress类使用方法
import java.net.*;
class IPDemo
{
public static void main(String[] args) throws Exception
{
InetAddress i=InetAddress.getLocalHost();
System.out.println(i.toString());
System.out.println("address:"+i.getHostAddress());
System.out.println("name"+i.getHostName());
InetAddress ia=InetAddress.getByName("www.baidu.com");//或者是IP地址
System.out.println("address:"+ia.getHostAddress());
System.out.println("name:"+ia.getHostName());
}
}
TCP和UDP介绍
一、TCP和UDP介绍
Socket介绍
UDP传输
UDP发送端
一、需求 通过udp传输方式,将一段文字发送出去1.建立udpsocket服务。
2.提供数据,并将数据封装到数据包中
3.通过socket服务的发送功能,将数据包发出去
4.关闭资源
二、代码
class UdpSend
{
public static void main(String[] args) throws Exception
{
//1.创建udp服务。通过DatagramSocket对象。
DatagramSocket ds=new DatagramSocket();
//2.确定数据,并封装成包。通过DatagramPacket对象
byte[] data="udp ge men lai la".getBytes();
DatagramPacket dp=new DatagramPacket(data,data.length,InetAddress.getByName("192.168.1.100"),10000);
//3.通过socket服务,将已有的数据包发送出去。通过send方法。
ds.send(dp);
//4.关闭资源
ds.close();
}
}
UDP接收端
一、需求 定义一个应用程序,用于接收udp协议传输的数据并处理。1.定义udpsocket服务。通常会监听一个端口。
其实就是给这个接收网络应用程序定义一个数字标示。方便于明确哪些数据过来改应用程序处理
2.定义一个数据包,因为要存储要接收到的字节数据。因为数据包对象中有更多功能,可以提取字节数据中的不同信息
3.通过scoket服务的receive方法将收到的数据存入到已定义好的数据包中。
4.通过数据包对象的特有功能,将这些不同的数据取出,打印到控制台上。
5.关闭资源
二、代码
class UdpReceive
{
public static void main(String[] args) throws Exception
{
//1.创建udp socket服务,建立端点。
DatagramSocket ds=new DatagramSocket(10000);//不能把创建socket服务放入下面的while循环,因为会反复创建调用同一端口的服务。
while(true)//为了保持接收端始终开放,所以用while循环。
{
//2.定义一个数据包。
byte[] data=new byte[1024];
DatagramPacket dp=new DatagramPacket(data,data.length);
//3.通过服务的receive方法将数据存入到数据包中
ds.receive(dp);
//4.通过数据包的方法获取其中的数据
String ip=dp.getAddress().getHostAddress();
new String(dp.getData(),0,dp.getLength());
int port=dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
}
//5.关闭资源
//ds.close();
}
}
UDP聊天
一、需求二、代码 1.发送方法
class Send implements Runnable
{
private DatagramSocket ds=null;
Send(DatagramSocket ds)
{
this.ds=ds;
}
public void run()
{
try
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String len=null;
while((len=br.readLine())!=null)
{
if("8888".equals(len))
break;
DatagramPacket dp=new DatagramPacket(len.getBytes(),len.getBytes().length,InetAddress.getByName("192.168.1.255"),10010);
ds.send(dp);
}
}
catch (Exception e)
{
throw new RuntimeException("数据发送端出现错误");
}
}
}
二、接收方法
class Receive implements Runnable
{
private DatagramSocket ds=null;
Receive(DatagramSocket ds)
{
this.ds=ds;
}
public void run()
{
try
{
while(true)
{
byte[] by=new byte[1024*64];
DatagramPacket dp=new DatagramPacket(by,by.length);
ds.receive(dp);
String address=dp.getAddress().getHostAddress();
String data=new String(dp.getData(),0,dp.getLength());
System.out.println(address+":"+data);
}
}
catch (Exception e)
{
throw new RuntimeException("数据接收端出现错误");
}
}
}
三、主函数
public static void main(String[] args) throws Exception
{
DatagramSocket sendSocket=new DatagramSocket();
DatagramSocket receiveSocket=new DatagramSocket(10010);
new Thread(new Send(sendSocket)).start();
new Thread(new Receive(receiveSocket)).start();
}
TCP传输
1.tcp分客户端和服务端。
2.客户端对应的对象是socket.
客户端对应的对象是serversocket
TCP客户端
一、需求需求:给服务端发送一个文本数据。
客户端:
通过查阅socket对象,发现在该对象建立时,就可以去连接指定的主机。
因为tcp是面向连接的。所以在建立socket服务时,就要有服务端存在,并连接成功。形成通路后,在该通道进行数据传输。
步骤:
1.创建Socket服务。并指定要连接的主机和端口
2.为了发送数据,应该获取socket流中的输出流。
二、代码
class TcpClient
{
public static void main(String[] args) throws Exception
{
//创建客户端的socket服务。指定目的主机和端口。
Socket s=new Socket("192.168.1.100",10003);
//为了发送数据,应该获取socket流中的输出流。
OutputStream out=s.getOutputStream();
out.write("tcp lai la".getBytes());
s.close();
}
}
TCP服务端
一、需求 定义端点接收数据并打印在控制台上服务端: 1.建立服务端的socket服务。通过ServerSocket(); 并监听一个端口 2.获取连接过来的客户端对象。通过ServerSocket的accept方法。没有连接就会等,所以这个方法是阻塞式的。 3.客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。 并打印在控制台 4.关闭服务端。(可选操作)
二、代码
import java.net.*;
class TcpServer
{
public static void main(String[] args)
{
//建立服务端的socket服务。并监听一个端口。
ServerSocket ss=new ServerSocket(10003);
//通过accept方法获取连接过来的客户端对象。
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"....connected");
//获取客户端发过来的数据,那么要使用客户端对象的读取流来获取数据。
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
s.close();//关闭客户端
ss.close();//可选。如果关闭,那么对外只服务一次。
}
}
TCP客户端和服务端的互访
一、需求 演示tcp的传输的客户端和服务端的互访。需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
二、客户端代码
1.建立socket服务。指定要连接的主机和端口。
2.获取socket流中的输出流。将数据写入该流中,通过网络发送给服务端。
3.接收socket流中的输入流。将服务端反馈的数据获取到,并打印。
4.关闭客户端资源。
class TcpClient2
{
public static void main(String[] args) throws Exception
{
Socket s=new Socket("192.168.1.101",10004);
OutputStream out =s.getOutputStream();
out.write("tcp lai la".getBytes());
InputStream in=s.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);//如果服务端没有返回数据,那么客户端会一直等待。
System.out.println(new String(buf,0,len));
s.close();
}
}
三、服务端代码
class TcpServer2
{
public static void main(String[] args) throws Exception
{
ServerSocket ss=new ServerSocket(10004);
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();//获取IP地址
System.out.println(ip+"....connected");
InputStream in =s.getInputStream();
byte[] buf =new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
OutputStream out=s.getOutputStream();
Thread.sleep(10000);//休眠10秒
out.write("wo shou dao ni de xin xi le".getBytes());
s.close();
}
}
TCP练习
一、需求 需求:建立一个文本转换服务器。客户端给服务端发送文本,服务端会将文本转成大写在返回给客户端,
而且客户端可以不断的进行文本转换。当客户端输入over时,转换结束。 都是文本数据,可以使用字符流进行操作,同时为了提高效率,加入缓冲技术。 二、客户端
既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。
源:键盘录入。
目的:网络设备,即网络输出流。
而且操作的是文本数据。可以选择字符流。
步骤:
1.建立服务。
2.获取键盘录入。
3.将数据发给服务端。
4.获取服务端返回的大写数据。
5.结束,关闭资源。
class TransClient
{
public static void main(String[] args) throws Exception
{
Socket s=new Socket("192.168.1.101",10005);
//定义读取键盘数据的流对象。
BufferedReader br=
new BufferedReader(new InputStreamReader(System.in));
//定义目的,将数据写入到socket输出流,发送给服务端。
BufferedWriter bwOut=
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//定义一个socket读取流,读取服务端返回的大写信息。
BufferedReader brIn=
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line =null;
while((line=br.readLine())!=null)
{
if("over".equals(line))
break;
bwOut.write(line);
bwOut.newLine();
bwOut.flush();
String str=brIn.readLine();
System.out.println("server:"+str);
}
br.close();
s.close();
}
}
三、服务器端
服务端:源:socket读取流。
目的:socket输出流。
class TransServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss=new ServerSocket(10005);
//服务器端获取socket
Socket s=ss.accept();
//获取连接到服务器的客户端的ip地址。
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"connected...");
//读取socket读取流中的数据。
BufferedReader br=
new BufferedReader(new InputStreamReader(s.getInputStream()));
//将大写数据写入到socket输出流。
BufferedWriter bw=
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
/*上面的一行代码可以简化。
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
*/
String str=null;
while((str=br.readLine())!=null)
{
bw.write(str.toUpperCase());
bw.newLine();
bw.flush();
/*
以上三行可以简化为
pw.println(str.toUpperCase());
*/
}
ss.close();
}
}
四、该练习需要注意的问题 现象:客户端和服务端都在莫名的等待。
为什么呢?
因为客户端和服务端都有阻塞式方法。这些方法没有读到结束标记,
那么两端就会一直等待。
例如上例:readLine()方法执行的条件是有换行符,如果不加换行符,则不能读取数据。
TCP文件复制——客户端把文件放到服务端存储
一、客户端代码import java.io.*;
import java.net.*;
class TcpCopyFileClient
{
public static void main(String[] args) throws Exception
{
Socket s=new Socket("192.168.1.101",10006);
BufferedReader br=
new BufferedReader(new FileReader("IPDemo.java"));
BufferedReader brs=
new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
String len=null;
while((len=br.readLine())!=null)
{
pw.println(len);
}
s.shutdownOutput();//如果不添加结束标示,那么会进入阻塞状态。
String str=brs.readLine();
System.out.println("server:"+str);
br.close();
s.close();
}
}
二、服务端代码
class TcpCopyFileServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss=new ServerSocket(10006);
Socket s=ss.accept();
PrintWriter pw=new PrintWriter(new FileWriter("server.txt"));
BufferedReader br=
new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter pws=new PrintWriter(s.getOutputStream(),true);
String len=null;
while((len=br.readLine())!=null)
{
pw.println(len);
}
pws.println("文件已经收到");
pw.close();
s.close();
ss.close();
}
}
TCP—客户端并发上传图片
一、客户端代码
class PicClient
{
public static void main(String[] args) throws Exception
{
if(args.length!=1)
{
System.out.println("请输入一个jpg文件");
return;//return 代表结束该函数。
}
File f=new File(args[0]);
if((!f.exists())&&(!f.isFile()))
{
System.out.println("文件要么不存在,要么不是文件");
return;
}
if(!f.getName().endsWith(".jpg"))
{
System.out.println("文件不是jpg文件");
return;
}
if(f.length()>1024*1024*5)
{
System.out.println("文件过大没安好心");
return;
}
Socket s=new Socket("192.168.1.101",10008);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(f));
BufferedOutputStream sbos=new BufferedOutputStream(s.getOutputStream());
BufferedInputStream sbis=new BufferedInputStream(s.getInputStream());
byte[] buf=new byte[1024];
int len=0;
while((len=bis.read(buf))!=-1)
{
sbos.write(buf,0,len);
}
s.shutdownOutput();
len=sbis.read(buf);
System.out.println(new String(buf,0,len));
s.close();
bis.close();
}
}
二、服务器端代码
1.线程类
class PicThread implements Runnable
{
private Socket s;
PicThread(Socket s)
{
this.s=s;
}
public void run()
{
String ip=s.getInetAddress().getHostAddress();
int count=0;
try
{
System.out.println(ip+"connected...");
File f=new File(ip+".jpg");
while(f.exists())
f=new File(ip+"("+(count++)+")"+".jpg");
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(f));
BufferedInputStream sbis=new BufferedInputStream(s.getInputStream());
BufferedOutputStream sbos=new BufferedOutputStream(s.getOutputStream());
byte[] buf=new byte[1024];
int len=0;
while((len=sbis.read(buf))!=-1)
{
bos.write(buf,0,len);
}
sbos.write("图片已经收到".getBytes());
sbos.flush();//用缓冲区输出流一定要记得刷新,否则会报异常。
s.close();
bos.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"文件上传失败");
}
}
}
2.服务器端主函数类
class PicServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss=new ServerSocket(10008);
while(true)
{
Socket s=ss.accept();
new Thread(new PicThread(s)).start();
}
//ss.close();
}
}
TCP客户端并发登陆
一、需求分析 客户端通过键盘录入用户名。 服务端对这个用户名进行校验。如果该用户存在,在服务端显示xxx已登陆。 并在客户端显示xxx,欢迎光临。
如果该用户存在,在服务端显示xxx,尝试登陆。 并在客户端显示xxx,该用户不存在。
最多就登陆三次。
二、客户端代码
class LoginClient
{
public static void main(String[] args) throws Exception
{
Socket s=new Socket("192.168.1.101",10009);
BufferedReader br=
new BufferedReader(new InputStreamReader(System.in));
BufferedReader sbr=
new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
for(int i=0;i<3;i++)
{
String name=br.readLine();
if(name==null)
break;
pw.println(name);
String info=sbr.readLine();
System.out.println("服务器:"+info);
if(info.contains("欢迎"))
break;
}
br.close();
s.close();
}
}
三、服务端代码
1.线程类
class UserLogin implements Runnable
{
private Socket s=null;
UserLogin(Socket s)
{
this.s=s;
}
public void run()
{
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"...connected");
BufferedReader sbr=null;
PrintWriter spw=null;
try
{
sbr=
new BufferedReader(new InputStreamReader(s.getInputStream()));
spw=
new PrintWriter(s.getOutputStream(),true);
}
catch (Exception e)
{
throw new RuntimeException(ip+"Socket输入输出流出现问题");
}
for(int i=0;i<3;i++)
{
BufferedReader br=null;
try
{
br=new BufferedReader(new FileReader("UserName.txt"));//分别补货异常后发现,该代码需要放在for循环内。因为要循环读取文件内容,如果不放在for内,会导致下次循环读取数据返回null,即已经访问到文件末尾。
}
catch (Exception e)
{
}
String name=null;
try
{
name=sbr.readLine();//该行在用户在客户端按下ctrl+c时,有时会报出异常,有时会正常返回null,具体异常原因不明,可能跟jdk1.7新特性有关。
if(s.isClosed())
break;
}
catch (Exception e)
{
throw new RuntimeException("输入流读取出现问题1");
}
if(name==null)
break;
String line=null;
boolean flag=false;
try
{
while((line=br.readLine())!=null)
{
System.out.println(line);
if(line.equals(name))
{
flag=true;
break;
}
}
}
catch (Exception e)
{
throw new RuntimeException("输入流读取出现问题2");
}
if(flag)
{
System.out.println(name+"登陆成功");
spw.println("登陆成功--欢迎");
break;
}
else
System.out.println(name+"尝试登陆");
spw.println(name+"登陆失败");
try
{
br.close();
}
catch (Exception e)
{
throw new RuntimeException("关闭异常1");
}
}
try
{
s.close();
}
catch (Exception e)
{
throw new RuntimeException("关闭异常2");
}
}
}
自定义浏览器客户端——Tomcat服务端
一、自定义浏览器客户端 1.浏览器需要发送给Tomcat服务器的信息 GET / HTTP/1.1 Host: 192.168.1.101:11000Connection: Keep-Alive
Accept:
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2
.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; SE 2.X MetaSr 1.0)
Accept-Encoding: gzip, deflate
以上为请求消息头,空一行之后的数据为:请求数据体
2.根据以上需要发送给服务器的信息,编写浏览器客户端的代码
import java.io.*;
import java.net.*;
class MyIE
{
public static void main(String[] args) throws IOException
{
Socket s=new Socket("192.168.1.101",8080);
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
pw.println("GET /myweb/demo.html HTTP/1.1");
pw.println("Accept: */*");
pw.println("Accept-Language: zh-cn");
pw.println("Host: 192.168.1.101:10001");
pw.println("Connection: Keep-Alive");
pw.println();//一定要输入一个空行,来区分消息头和消息体
pw.println();
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String str=null;
while((str=br.readLine())!=null)
{
System.out.println(str);
}
s.close();
}
}
二、Tomcat6.0服务器
1.在tomcat的bin目录下找到startup启动tomcat服务器
2.在webapps文件夹下创建一个文件夹——myweb,并在该文件夹下创建demo.html,代码如下
<html>
<body>
<h1>欢迎进入我的网站</h1>
<font size=5 color=blue>欢迎光临</font>
<div>
撒旦啊实打实大师阿斯顿阿斯顿爱死</br>
撒大声地阿斯顿阿斯顿爱死大声道爱</br>
飒飒大师的阿斯顿阿斯顿爱死爱死阿</br>
</div>
</body>
</html>
自定义图形界面浏览器——Tomcat服务器
一、代码<pre name="code" class="java">import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
class MyIEGUI
{
private Frame f;
private Button b;
private TextField tf;
private TextArea ta;
MyIEGUI()
{
init();
}
private void init()
{
f=new Frame("my frame");
f.setBounds(300,200,500,600);
f.setLayout(new FlowLayout());
tf=new TextField(40);
b=new Button("转到");
ta=new TextArea(30,50);
f.add(tf);
f.add(b);
f.add(ta);
DemoEvent();
f.setVisible(true);
}
public void DemoEvent()
{
/*1*/f.addWindowListener(new WindowAdapter()//监听f的WindowEvent e
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
/*4*/b.addActionListener(new ActionListener()//监听b的ActionEvent
{
public void actionPerformed(ActionEvent e)
{
show();
}
});
/*5*/tf.addActionListener(new ActionListener()//监听tf的ActionEvent
{
public void actionPerformed(ActionEvent e)
{
show();
}
});
}
public void show() //将在TextField按下回车和点击Button做出的相同的事件响应进行封装
{
ta.setText("");
String url=tf.getText();
int index1=url.indexOf("//")+2;
int index2=url.indexOf("/",index1);
String host=url.substring(index1,index2);
String path=url.substring(index2);
String[] arr=host.split(":");
String ip=arr[0];
int port =Integer.parseInt(arr[1]);
socket(ip,port,path);
}
public void socket(String ip,int port,String path)
{
try
{
Socket s=new Socket(ip,port);
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
pw.println("GET "+path+" HTTP/1.1");
pw.println("Accept: */*");
pw.println("Accept-Language: zh-cn");
pw.println("Host: "+ip+":"+port);
pw.println("Connection: Keep-Alive");
pw.println();//一定要输入一个空行,来区分消息头和消息体
pw.println();
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String str=null;
while((str=br.readLine())!=null)
{
ta.append(str+"\r\n");
}
s.close();
}
catch (Exception e)
{
throw new RuntimeException("出现异常");
}
}
public static void main(String[] args)
{
new MyIEGUI();
}
}
URL——URLConnection
一、概述 类URL
代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
通过
二、方法
1.获取此 URL
的文件名。
String getFile()
2.获取此 URL
的主机名(如果适用)。
String getHost()
3.获取此 URL
的路径部分。
String getPath()
4.获取此
URL
的端口号。
int getPort()
5.获取此 URL
的协议名称。
String getProtocol()
6.获取此 URL
的查询部分
String getQuery()
其中,getFile()方法等于getPath()+getQuery();
三、代码
上一节中的show()和socket()可用以下代码替换
public void show()
{
try
{
URL url=new URL(tf.getText());
URLConnection uc=url.openConnection();
BufferedReader is=new BufferedReader(new InputStreamReader(uc.getInputStream(),"utf-8"));
ta.setText("");
String str=null;
while((str=is.readLine())!=null)
{
ta.append(str+"\r\n");
}
}
catch (Exception e)
{
throw new RuntimeException("出现异常");
}
}
相关文章
- 暂无相关文章
用户点评