网络是按照网络协议进行运行的(tcp/ip协议),我们经常使用的程序是在最上层上面的使用,分为应用层,传输层,网络层,链路层,物理层。每一个连接到这个协议的设备都会有一个ip地址的,一般是一个32位的二进制整数。数据的传输是通过传输层来传输的。
但是每一个应用程序都需要连接网络,ip地址只有一个怎么解决这么多的应用程序都需要上网的问题呢,那就需要通过端口了,一个端口和一个ip地址形成了套接字(支持通信的基本单元)。端口号可以从0~65535.但是0~1023被系统使用了,所以最好使用1023以后的,除非和系统进行连接什么的。
传输层:
是通过tcp/ip协议来控制通信,分为tcp协议和udp协议,tcp协议具有可靠性和有序性,通过字节流进行传输(不过必须先进行连接才能传输否则不可能传输)。
而udp协议是一种无连接的传输协议,它先把数据定义成数据报,然后在往指明的端口发送,当然这种传输 是无序的,而且不安全,但是它的传输效率却很高。
java中有以下几种方式:
InetAddress:专门用来获得ip。
URL:获得资源的地址,可以获得资源,也可以传输资源。
Socket:使用tcp协议进行传输。
Datagram:通过UDP协议来传输。
InetAddress
它是一个构造函数是私有变量的类,所以不能New,但是可以通过它提供的静态函数来使用.
例如: getByName(string host)//可以通过地址的Ip地址。
getLocalHost()//获得自己的机子名和ip地址。
package com.ip;
import java.net.*;
public class myIp {
public static void main(String[] args) {
// TODO Auto-generated method stub
InetAddress hc = null;
try {
hc=InetAddress.getLocalHost();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(hc);
}
}
URL
是网上资源定位器。
protocol://host_name:port_number/file_name/reference
protoco:指的是传输协议:http/ftp等;
host_name:主机名。
port_number:端口。
file_name:具体的文件名。
reference:资源。
举个例子 http://www.baidu.com/~vmi/java/html。
在使用的时候会遇到相对地址和绝对地址的问题。
那么来解释一下:
绝对地址很好理解比如说你在D盘image里有个交p的图片。那么绝对地址就是:D:\image\p.jpeg.
如果你现在就打开D盘,那么照片的位置就是image/p.jpeg。
这就是相对位置,相对于你当前位置的地址。(一般来说多用相对,少用绝对)。
对于一个URL对象:
String getProtocol()//获得传输协议
String getHost()//获得机器名字
String getPort()//获得端口
String getFile()//获得文件资源文件。
在使用URL读取数据的时候需要用到openStream()的方法来指点资源。
package com.ip;
import java.net.*;
import java.io.*;
public class url {
public static void main(String[] args) {
// TODO Auto-generated method stub
URL root=null;
URL url=null;
String s;
DataInputStream m=null;
try {
root=new URL("file://10.93.121.28/program/cc");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Socket:
通过tcp协议进行传输的。
通过它实现,可以创建一个服务器端,然后有很多客户端。这样就可以通过客户端—》服务器-》客户端来进行客户端和客户端的通信,也可以进行客户端和服务器之间的通信。
服务器首先要建立一个端口,为了让客户端接入。
package com.ip;
import java.io.*;
import java.net.*;
public class fuwuqi1 {
InputStreamReader c=null;
ServerSocket ss=null;
public fuwuqi1()
{
try {
ss = new ServerSocket(9999);//设置了端口为9999
Socket s = ss.accept();
c = new InputStreamReader(s.getInputStream());
BufferedReader buff = new BufferedReader(c);
while(true)
{
System.out.println(buff.readLine());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new fuwuqi1();
}
}
package com.ip;
import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class kehuduan1 extends JFrame implements ActionListener {
JPanel p=null;
JTextArea area=null;
JScrollPane pane=null;
JTextField field=null;
JButton button=null;
PrintWriter writer=null;
public kehuduan1()
{
p=new JPanel();
area=new JTextArea();
pane=new JScrollPane ();
field=new JTextField(20);
button=new JButton("发送");
button.addActionListener(this);//这些就是做个界面可以无视
pane.setViewportView(area);;
p.add(field);
p.add(button);
this.add(p,BorderLayout.SOUTH);
this.add(pane);
this.setSize(500, 500);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
this.setVisible(true);
try {
Socket net=new Socket("127.0.0.1",9999);//找到你需要连接的地址和端口
writer =new PrintWriter(net.getOutputStream(),true);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource()==button)
{
String s=field.getText();
area.append(s+"\r\n");
writer.println(s);
field.setText("");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new kehuduan1();
}
}
这里我还要说一下我最近一直遇到的一个问题:
就是在socket传输中使用了outputstreamwriter然后在使用inputstreamreader,并且把inputstreamreader放在缓存中然后读取,使用readline()怎么读都无法读取,想了很久也不知道是为什么,找了几天资料才发现readline()需要在遇到\r \n或者是\r\n的时候才会停止读,不然就会一直读不设定就不会停止,除非是遇到错误了。
因为outputstreamwriter传一个很普通的字符串是不可能的,因为字符串中没有这些标记,会不停的读,因为可以把outputstreamwriter换成Printwriter,Printwriter会在写入的时候格式化字符串,让它有了标记,那么就可以停下了。当然也可以DataInputstream和Dataoutputstream。
但是这并不是最好的,最好就是对象流这样安全,简洁。
睡觉
~\(≧▽≦)/~