您的位置:首页 > 理论基础 > 计算机网络

黑马程序员_网络编程(非常重要)

2013-04-28 09:30 323 查看
----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

网络通讯要素:

IP地址:(InetAddress)网络中设备的标识。不易于记忆,可以用主机名。

本地回环地址:127.0.0.1主机名:localhost

端口号:用于标识程序的逻辑地址,不同进程的标识。

有效端口:0~65535,其中0~1024系统使用或者保留端口,最好不要使用。

传输协议:通讯的规则。

常见协议:

UDP:

将数据及源和目的封装成数据包,不需要建立连接。

每个数据大小限制在64k之内。

因为无连接,所以是不可靠协议(没有目的地直接丢弃),但是速度快。

TCP:(必须建立连接,无连接不通信)

建立连接,形成传输数据的通道。

在连接中进行大数据量传输。

通过三次握手完成连接,是可靠协议。

必须建立连接,效率稍低。

IP对象:InetAddress:构造方法私有,不能直接创建对象。

InetAddressgetByName(String host):在给定主机名的情况下确定主机的ip地址。

InetAddressgetLocalHost():返回本地主机。

InetAddress[]getAllByName(String host)

ip.getHostAddress(), ip.getHostName()

域名解析:

DNS域名解析服务器

网络传输需要通过Socket来实现

Socket(插座):套接字

Socket就是为网络服务提供的一种机制。

通信的两端都有Socket。Socket是网络通讯的端点。

网络通信其实就是Socket间的通信。

数据在两个Socket间通过IO传输。

UDP传输:

DatagramSocket:表示用来发送和接收数据报包的套接字。

DatagramPacket:用来实现无连接包投递服务每条报文根据该包中包含信息从一台机器路由到另一台机器。

建立UDP接收端的思路。

1.建立UDP socket服务。因为是接收数据,要明确接收的是哪个端口的数据。

2.创建数据包用于存储接收到的数据。方便用数据包对象的方法解析这些数据。

3.使用socket服务的receive方法,将接收的数据存储到数据包中。

4.通过数据包的方法解析数据包中的数据。

5.关闭资源。

创建UDP传输的发送端思路:

1.建立UDP的Socket服务。

2.将要发送的数据封装到数据包中。

3.通过UDP的Socket服务将数据包发送出去。

4.关闭Socket服务。

/**
* 有图形界面的网络聊天室
* @author 张熙韬
*
*/
public class XiaoSaGeChat {

DatagramSocket ds = null;
Thread thread = null;
Frame frame = new Frame("潇洒哥的聊天室");
TextField ip = new TextField(15);
List list = new List(10);
Panel panel = new Panel();
Button ok = new Button();
TextField content = new TextField(15);

public XiaoSaGeChat() {
try {
ds = new DatagramSocket(3000);
} catch (SocketException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
XiaoSaGeChat chat = new XiaoSaGeChat();
chat.init();
}

public void listener(ActionEvent e){
byte[] buffer;
buffer = e.getActionCommand().getBytes();
DatagramPacket dp = null;
try {
// 将内容发送给指定IP
dp = new DatagramPacket(buffer, buffer.length, InetAddress
.getByName(ip.getText()), 3000);
ds.send(dp);
} catch (Exception e1) {
e1.printStackTrace();
}

}

public void init() {
frame.setSize(300, 300);
frame.add(list);
list.setBackground(Color.PINK);
panel.setLayout(new BorderLayout());
panel.add(BorderLayout.WEST, ip);

panel.add("East", content);

frame.add("South", panel);
// 设置窗口大小可更改
frame.setResizable(true);
frame.setVisible(true);
ok.setLabel("发送");
panel.add("Center", ok);
ok.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
listener(e);
/*byte[] buffer;
buffer = content.getText().getBytes();
DatagramPacket dp = null;
try {
dp = new DatagramPacket(buffer, buffer.length, InetAddress
.getByName(ip.getText()), 3000);

ds.send(dp);
} catch (Exception e1) {
if (!ds.isClosed()) {
e1.printStackTrace();
}
}*/
content.setText("");
}
});

new Thread(new Runnable() {
public void run() {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
while (true) {
try {
ds.receive(dp);
list.add(new String(buf, 0, dp.getLength())
+ "    IP地址:"
+ dp.getAddress().getHostAddress() + " 端口号: "
+ dp.getPort(), 0);
} catch (IOException e) {
if (!ds.isClosed()) {
e.printStackTrace();
}
}
}
}
}).start();

frame.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {
ds.close();
frame.setVisible(false);
frame.dispose();
System.exit(0);
super.windowClosing(e);
}
});

content.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

listener(e);
((TextField) e.getSource()).setText("");// 最初发生 Event 的对象。
}
});

}

}


----------------------------------------------------------------------------

TCP:

Socket(客户端套接字)和ServerSocket(服务端)

TCP传输,客户端建立的过程。

客户端发送数据到服务端。

1.创建tcp客户端socket服务,使用的是socket服务。

建议对象一创建就明确目的地。要连接的主机。

2.如果连接建立成功,就说明数据传输通道已建立。

该通道就是Socket流是底层建立好的。既然是流,说明既有输入,又有输出

想要输入或者输出流对象,可以找Socket来获取。

可以通过getInputStream()和getOutputStream()来获取两个字节流。

3.使用输出流,将数据写出。

4.关闭资源。

建立TCP服务端的思路:

1.创建服务端Socket服务,通过ServerSocket

2.服务端必须对外提供一个端口,否则客户端无法连接。

3.获取连接过来的客户端对象。

4.通过客户端对象获取socket流读取客户端发来的数据。

打印在控制台上。

5.关闭资源。关客户端,关服务端。

Socket类的方法:

shutdownOutput():禁用此套接字的输出流,既结束此流。

shutdownInput():

-------------------------------------------------------------------------------------------------------------------

/*
服务端

这个服务端有个局限性。当A客户端连接上以后。被服务端获取到。服务端执行具体流程。
这时B客户端连接,只有等待。
因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法。所以
暂时获取不到B客户端对象。

那么为了可以让多个客户端同时并发访问服务端。
那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。

如何定义线程呢?

只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。
*/

class PicThread implements Runnable
{

private Socket s;
PicThread(Socket s)
{
this.s = s;
}
public void run()
{

int count = 1;
String ip  = s.getInetAddress().getHostAddress();
try
{
System.out.println(ip+"....connected");

InputStream in = s.getInputStream();

File dir =  new File("d:\\pic");

File file = new File(dir,ip+"("+(count)+")"+".jpg");

while(file.exists())
file = new File(dir,ip+"("+(count++)+")"+".jpg");

FileOutputStream fos = new FileOutputStream(file);

byte[] buf = new byte[1024];

int len = 0;
while((len=in.read(buf))!=-1)
{
fos.write(buf,0,len);
}

OutputStream out = s.getOutputStream();

out.write("上传成功".getBytes());

fos.close();

s.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"上传失败");
}
}
}

class  PicServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10007);

while(true)
{
Socket s = ss.accept();

new Thread(new PicThread(s)).start();

}

//ss.close();
}
}


----------------------------------------------------------------

常见的客户端:浏览器 IE

常见的服务端:服务器 Tomcat

为了了解其原理:

1.自定义服务端,使用已有的客户端IE,了解下客户端给服务器端发送了什么请求。

发送的请求是:

GET/ HTTP1.1请求行:请求方式/myweb/.html

请求的资源路径,http协议版本

请求消息头:属性名:属性值

空行

请求体(请求头和请求体之间有行空格)

服务端发回的应答消息。

应答行,http的协议版本,应答状态码,应答状态描述信息。

应答消息属性信息。属性名:属性值

应答体。

URL:同一资源定位符。指向互联网资源的指针。

URI:统一资源标识符。

URN:统一资源名称。

每个URL都是URI,定位符是标识符中的一种。

URL对象可以直接解析URL地址。

StringgetProtocol();获取此URL的协议名称。

StringgetHost();获取此URL的主机名

--------------------------------------

intgetPort()获取此URL的端口号

没有获取到端口号的时候,端口号默认-1;

-------------------------------------

StringgetPath();获取此URL的路径

StringgetFile()获取此URL的文件名

URLConnection conn = url.openConnection();

InputStream in = conn.getInputStream();

相当于:

InputStream in = url.openStream();

ServerSocket创建时可以传入两个参数,一是端口号,而是最长队列长度

也就是允许的最大的客户端连接数量

两种常见的网络结构:

网络架构:

C/S:Client/Server

客户端,服务端。

特点:

1,需要在客户端和服务端都需要按照编写的软件。

2,维护较麻烦。

好处:可以减轻服务端的压力,如网络游戏。

B/S:Browser/Server

浏览器 ,服务端。

1,客户端不用单独编写软件。

因为客户端用的就是浏览器。

2,对于软件升级,只要考虑服务端即可。

弊端:所有的程序都运行在服务端,客户端的浏览器毕竟解析能力较弱。对游戏等。

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: