黑马程序员——网络编程
2015-12-27 11:08
465 查看
-------
android培训、java培训、期待与您交流! ----------
网络编程
网络通讯步骤:
1. 找到IP2. 找到指定端口
3. 找到通讯规则,协议
我做的app没法通过数据连接上网的原因是,我的IP地址是局域网的IP,不是公网的IP,所以没法用,不是公网分给我的IP
常见的端口:
Web服务80tomcat服务器8080
mysql,3306
常见协议:TCP 和UDP
一、网络模型
OSI参考模型 : 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层TCP/IP参考模型:应用层(HTTP/FTP),传输层(TCP,UDP),网际层(IP),主机至网络层
二、网络通讯要素:
IP地址:网络中设备的标识
本地回环地址:127.0.0.1默认localhost
//获取主机名
InetAddress i=InetAddress.getLocalHost();
System.out.println(i.toString());
System.out.println(i.getHostAddress());
System.out.println(i.getHostName());
获取任意一台主机IP地址InetAddress
InetAddress is=InetAddress.getByName("www.baidu.com");
System.out.println(is.getHostAddress());
返回的IP对象可能不唯一,有可能返回一个数组
端口号:用于标识进程的逻辑地址,不同进程的标识
有效端口:0-65535,其中0-1024保留端口
传输协议:TCP,UDP(udp必须会)
udp面向无连接的,不可靠,速度快每个数据包的大小在64k内。
聊天,视频会议等都是UDP
TCP建立连接,在连接中传输数据,通过三次握手连接,可靠,效率低,必须建立连接
三、 TCP传输:
tcp分客户端和服务端,客户端对应的是Socket,服务端对应的是ServerSocket客户端,在对象建立时就可以连接主机,所以在客户端建立时就要有服务端存在
步骤:
//创建客户端的socket服务,指定主机和端口号
Socket s=new Socket("192.168.0.105",10005);
//获取socket中的输出流,写数据到服务端
OutputStreamos=s.getOutputStream();
os.write("ge lai le".getBytes());
os.close();
服务端:
1. 建立服务端的serversocket,并监听一个端口
2. 获取连接过来的客户端对象,通过accept方法,这个方法是阻塞式的,没有连接就会等
3. 客户端如果发过来数据,服务端要使用对应 的客户端对象,并获取到该客户端对象的读取流来读取数据,并打印
4.关闭服务端,可以不关
public class Server {
public
static void main(String args[])throws IOException {
ServerSocket serv = new ServerSocket(10005);
Socket s = serv.accept();
InputStream is = s.getInputStream();
byte[] buf =newbyte[1024];
int len = is.read(buf);
String str = new String(buf, 0, len);
System.out.println(str);
String s1 = s.getInetAddress().getHostAddress();
System.out.println(s1);
s.close();
}
}
四、 例子
要求客户端给服务端发送文本,服务端把接收到的文本转换为大写输出到客户端分析:客户端:
源:键盘输入。目的:网络设备,网络输出流
文本数据,可以选择字符流
步骤:1.建立服务
2.获取键盘录入
3.将数据发给服务器
4.服务器返回大写数据
5.关闭资源
客户端:
public
class Client {
public
static void main(String[] args)throws IOException {
Socket so=new Socket("192.168.0.105",10005);
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufout=new BufferedWriter(new OutputStreamWriter(so.getOutputStream()));
BufferedReader bufin=new BufferedReader(new InputStreamReader(so.getInputStream()));
String line=null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
bufout.write(line);
bufout.newLine();//加一个回车符,方便服务端返回数据
bufout.flush();//如果不刷新,就把数据写不过去
String str=bufin.readLine();
System.out.println(str);
}
bufr.close();
so.close();
}
}
服务端:
public
class Server {
public
static void main(String args[])throws IOException {
ServerSocket ss=new ServerSocket(10005);
Socket so=ss.accept();
String ip=so.getInetAddress().getHostAddress();
System.out.println("ip"+ip);
BufferedReader bufr=new BufferedReader(new InputStreamReader(so.getInputStream()));
// BufferedWriter bufw=new BufferedWriter(newOutputStreamWriter(so.getOutputStream()));
PrintWriter pw=new PrintWriter(so.getOutputStream(),true);
String s=null;
while((s=bufr.readLine())!=null){//如果没有回车符,那么readline不会返回数据,会继续等待
/*bufw.write(s.toUpperCase());
bufw.newLine();
bufw.flush();*/
pw.println(s.toUpperCase());
}
so.close();
ss.close();
}
}
这边出现的问题,两边都有阻塞式方法,readline。如果没有换行标记,那么会一直等待,还有两边都加了缓冲,如果不用flush刷新,那么就会一直在缓冲里面,不会出来,所以既要加换行,又要加刷新
上传文件到服务器:
客户端//1.读取文件
//2.把文件写入到服务器
Socket s=new Socket("192.168.0.105",10005);
BufferedReader bufr=new BufferedReader(new FileReader("file.txt"));
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
String str=null;
while((str=bufr.readLine())!=null){
pw.println(str);
}
s.shutdownOutput();
BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
String s1=bufin.readLine();
System.out.println(s1);
bufin.close();
s.close();
服务器端:
ServerSocket ss=newServerSocket(10005);
//1.接收来自客户端的数据
//2.把接收到的数据存入文件,放入f盘
//3.向客户端打印收到数据
Socket s=ss.accept();
String s1=s.getInetAddress().getHostAddress();
System.out.println(s1);
BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bufw=new BufferedWriter(new FileWriter("f:\\file.txt"));
String line=null;
while((line=bufr.readLine())!=null){
bufw.write(line);
}
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
pw.println("收到数据");
s.close();
bufw.close();
ss.close();
上传图片
客户端:
//1.把图片读取出来
//2.把图片写入到服务器
//3.把流关闭
Sockets=newSocket("192.168.0.105",10005);
FileInputStream is=new FileInputStream("d:\\qin1.jpg");
OutputStream out=s.getOutputStream();
byte[] b=newbyte[1024];
int len=0;
while((len=is.read(b))!=-1){
out.write(b,0,len);
}
s.shutdownOutput();
InputStream in=s.getInputStream();
int lenth=in.read(b);
String str=new String(b,0,lenth);
System.out.println(str);
s.close();
is.close();
服务端
ServerSocket ss=newServerSocket(10005);
Socket socket = ss.accept();
System.out.println("连接成功");
InputStream is=socket.getInputStream();
FileOutputStream out=new FileOutputStream("f:\\秦1.jpg");
byte[] b=newbyte[1024];
int len=0;
while((len=is.read(b))!=-1){
out.write(b,0,len);
}
OutputStream os=socket.getOutputStream();
os.write("上传图片成功".getBytes());
os.close();
socket.close();
并发上传图片:
服务端程序:public
class Server {
public
static void main(String args[])throws IOException {
ServerSocket ss=new ServerSocket(10005);
while(true){
Socket socket = ss.accept();
Date date=new Date();
System.out.println(date+"连接成功");
new Thread(new PicThread(socket)).start();
}
}
}
class PicThreadimplements Runnable{
Socket socket=null;
PicThread(Socket s){
this.socket=s;
}
@Override
public
void run() {
InputStream is;
try {
is = socket.getInputStream();
FileOutputStream out=new FileOutputStream("f:\\秦1.jpg");
byte[] b=newbyte[1024];
int len=0;
while((len=is.read(b))!=-1){
out.write(b,0,len);
}
OutputStream os=socket.getOutputStream();
os.write("上传图片成功".getBytes());
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
并发登陆
客户端-Socket so = newSocket("192.168.0.105", 10005);
InputStream is = System.in;
BufferedReader bufr = new BufferedReader(new InputStreamReader(is));
// PrintWriter pw=newPrintWriter(so.getOutputStream(),true);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
so.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(
so.getInputStream()));
for (int i = 0; i < 3; i++) {
String name = bufr.readLine();
if (name ==null)
break;
// pw.println(name);
out.write(name);
out.newLine();
out.flush();
String line = in.readLine();
System.out.println(line);
if (line.contains("欢迎")) {
break;
}
}
bufr.close();
so.close();
服务端-
public
class Server {
public
static void main(String args[])throws IOException {
ServerSocket ss = new ServerSocket(10005);
while (true) {
Socket socket = ss.accept();
Date date = new Date();
System.out.println(date +"连接成功");
new Thread(new PicThread(socket)).start();
}
}
}
class PicThreadimplements Runnable {
Socket socket = null;
PicThread(Socket s) {
this.socket = s;
}
@Override
public
void run() {
InputStream is;
File file = new File("f:\\user.txt");
try {
for (int i = 0; i < 3; i++) {
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String name = in.readLine();
BufferedReader bufr = new BufferedReader(new FileReader(file));
boolean flag =false;
String line = null;
while ((line = bufr.readLine()) !=null) {
if (line.equals(name)) {
flag = true;
break;
}
}
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
if (flag) {
pw.println("欢迎光临");
break;
} else {
pw.println("用户不存在");
}
}
socket.close();
} catch (Exception e) {
throw
new RuntimeException("校验失败");
}
}
}
浏览器也可以作为客户端来访问服务器,在地址栏输入:IP+端口号就可以访问这个应用程序,也可以返回和解析结果
如果客户端是浏览器,服务端是tomcat服务器的话也一样。只不过tomcat里面封装了socket
URL类的用法
URLConnection把Socket封装到里面了,从URLconnection里面获取的数据没有响应头,是属于应用层的对象,而不是传输层的域名解析:比如www.sina.com.cn把主机名翻译成IP地址就需要域名解析,就需要到公网找一台域名解析服务器DNS ,DNS服务器里面都是主机名(新浪)对应的IP地址(www.sina.com.cn)。找到对应的IP地址之后就把IP地址返回给浏览器,浏览器再次发送请求,请求刚才返回来的IP地址,这样才访问到新浪的服务器的
为什么localhost和127.0.0.1对应?
他们的映射关系就在本机上,c:\windows\systems32\drivers\ext\host
补充知识:8080是tomcat的端口,80是web服务器的端口,平时我们不输入80,那么它的返回值是-1,然后再把80赋值给端口号,所以就访问了80了。
当我们访问地址的时候,先去找的本地的主机,然后才找的互联网的DNS服务器,如果在本地配置其它网站的IP-主机名,那么就不走互联网DNS,直接在本地就开始访问IP了,速度比较快,如果不知道主机名的IP地址可以通过如下方法拿到其IP
InewAddress.getByName(“www.sina.com.cn”)
如果myeclipse要收费,把127.0.0.1配置给www.myeclipse.com那么启动的时候就找不到其网址,不能进行验证
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序