/ *
【UDP传输:无连接传输协议】
Udp发送端:
1.建立Udpsocket服务
2.提供发送的数据并封装成数据报。
3.通过Socket套接字服务的发送功能,将数据报发送出去。
4.关闭资源。
* /
import java.net.*;
class UdpSendDemo
{
public static voidmain(String[] args) throws Exception{
//1.创建UDP服务
DatagramSocketds = new DatagramSocket(8888);
//2.确定数据,并封装成包
byte[] buf ="I am coming!".getBytes();
DatagramPacketdp = new DatagramPacket(
buf,buf.length,InetAddress.getByName("192.168.1.100"),12000);
//3.通过socket服务,将已有的数据发送出去,通过send方法
ds.send(dp);
//关闭资源
ds.close();
}
}
/ *
【接收UDP协议传输的数据】
1.定义udpsocket服务。通常会监听一个端口。
即定义一个数字标识,方便于明确哪些数据进行处理。
2.定义一个数据包,要存储接收到的字节数据。
因为数据包对象中有更多功能,可以提取字节数据中的不同数据信息。
3.通过socket服务的receive方法将受到数据存入已定义的好的数据包中。
4.通过数据包对象特有功能,将这些不同数据取出,打印。
5.关闭资源。
* /
class UdpRece
{
public static voidmain(String[] args) throws Exception{
//1.建立udp socket建立端点
DatagramSocketds = new DatagramSocket(12000);
while (true)
{
//2.定义数据包,用于存储待接收数据
byte[]buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//通过服务的receive方法接收数据,存入定义好的数据包中。
//阻塞式方法,等待接收数据。接收到数据则唤醒。
ds.receive(dp);
//通过数据包中方法获取其中数据
String ip= dp.getAddress().getHostAddress();
Stringdata = new String(dp.getData(),0,dp.getLength());
int port= dp.getPort();
System.out.println(ip+":"+port+":"+data);
}
//关闭连接。
//ds.close();
}
}
//控制台聊天程序
import java.io.*;
import java.net.*;
class Send implements Runnable
{
private DatagramSocketds;
private int port;
Send(DatagramSocketds,int port){
this.ds = ds;
this.port =port;
}
public void run(){
BufferedReaderbw ;
try{
bw = newBufferedReader(new InputStreamReader(System.in));
Stringline;
while((line = bw.readLine())!=null){
if(!line.equals("over")){
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(
buf,buf.length,InetAddress.getByName("192.168.1.102"),port);
ds.send(dp);
}else
break;
}
ds.close();
}
catch (Exceptione){}
}
}
class Receive implements Runnable
{
private DatagramSocketds;
Receive(DatagramSocketds){
this.ds = ds;
}
public void run() {
while (true){
byte[]buf = new byte[1024*64];//udp协议数据包最大为64K
DatagramPacket dp = new DatagramPacket(buf,buf.length);
try{ds.receive(dp);}catch(Exception e){}
String ip= dp.getAddress().getHostAddress();//toString()?
intportex = dp.getPort();
Stringdata = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+"------"+portex+"::"+data);
}
}
}
class ChatTest_1
{
public static voidmain(String[] args) throws Exception{
try{
newThread (new Send(
new DatagramSocket(6666),7777)).start();
newThread (new Receive(
new DatagramSocket(8888))).start();
}
catch (Exceptione){
throw e;
}
}
}
class ChatTest_2
{
public static voidmain(String[] args) throws Exception{
try{
newThread (new Send(
new DatagramSocket(5555),8888)).start();
newThread (new Receive(
new DatagramSocket(7777))).start();
}
catch (Exceptione){
throw e;
}
}
}
/ *
---------------------------------------------------------
【TCP传输控制协议】:
客户端对应的对象是Socket
服务器对应的对象是ServerSocket
客户端:
Socket在建立对象时,就可以去连接指定的主机。
因为tcp是面向连接的。
所以在建立socket服务时,就要有服务器存在,并连接成功。
形成通路后,在该通道进行数据的传输。
步骤:
1.创建Socket服务,并指定要连接的主机和端口。
2.获取Socket服务中的输出流,将数据写到该流中,通过网络发送给客户端。
3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
4.关闭客户端资源。
* /
import java.net.*;
import java.io.*;
class TCPClient
{
public static voidmain(String[] args) throws Exception
{
//创建客户端的Socket服务,指定目的主机和端口。
Socket s = newSocket("192.168.1.101",10003);
//为了发送数据,应该获取Socket流中的输出流
OutputStream out= s.getOutputStream();
out.write("Client is coming".getBytes());
InputStream in =s.getInputStream();
byte[] buf = newbyte[1024];
int len = in.read(buf);//read也是阻塞式方法,因此收发不会冲突
System.out.println(new String(buf,0,len));
s.close();
}
}
/ *
需求:定义端点接收数据并打印在控制台上
服务器端:
1.建立服务端的ServerSocket服务,并监听一个端口。
2.获取连接过来的客户端对象。
通过accept方法完成。这个方法是阻塞式的。
3.客户端如果发来数据,服务端要使用对应的客户端对象,并获取该客户端对象的读取流,
读取发来的数据,打印在控制台。
4.关闭服务器(可选)
* /
class TCPServer
{
public static voidmain(String[] args) throws Exception
{
//建立服务端ServerSocket服务,并监听一个端口
ServerSocket ss= new ServerSocket(10003);
//通过accep方法获取连接到的客户端对象
Socket s =ss.accept();
String ip =s.getInetAddress().getHostAddress();
System.out.println(ip+"......connected");
//获取客户端发送过来的数据,需要使用客户端对象的读取流来读取数据
InputStream in = s.getInputStream();
byte[] buf = newbyte[1024];
int len =in.read(buf);
System.out.println(new String(buf,0,len));
OutputStream out= s.getOutputStream();
Thread.sleep(5000);
out.write("Server is connected.".getBytes());
s.close();
ss.close();
}
}
/ *
服务器端使用单线程的局限性:
当A客户端连接上服务器,服务执行具体的流程,当B线程连上服务器需要执行操作,则需要等待。
因为服务端未处理完A客户端的请求,无法返回执行accept方法,暂时获取不到B客户端对象。
为了让多个客户端同时并发访问服务端,最好就是将每个客户端封装到一个单独的线程中
这样就可以同时处理多个客户端请求。
如何定义线程?
只要明确了每一个客户端要在服务端执行的代码,将该代码置入run方法中。
* /
package cn.edward;
import java.io.*;
import java.net.*;
public class PicClient
{
public static voidmain(String[] args) throws Exception{
Socket s = newSocket("192.168.1.101",8888);
//读入源文件之前先进行文件存在,文件格式,文件大小的限制性判断。
File file = newFile("F:\\我的文档\\Pictures\\零照\\20101015.jpg");
if(!(file.exists()&&file.isFile())){
System.out.println("指定文件不存在");
}
if(!(file.getName().endsWith(".jpg"))){
System.out.println("文件格式有误");
}
if (file.length()>1024*1024*5){
System.out.println("文件过大,无法上传");
}
FileInputStream is =new FileInputStream(file);
OutputStream outs =s.getOutputStream();
//读取图片文件的内容,并发送给服务器端
byte[] buf = newbyte[1024];
int len =0;
while ((len =is.read(buf))!=-1){
outs.write(buf,0,len);
}
//关流操作,让服务器收到终止标记,停止read方法的阻塞。不管流则造成双方同时阻塞
s.shutdownOutput();
//读取服务器端反馈的信息
InputStream ins =s.getInputStream();
byte[] bufin = newbyte[1024];
int exlen= 0;
while ((exlen=ins.read(bufin))!=-1){
System.out.println(new String(bufin,0,exlen));
}
//关闭流对象以及套接字对象
is.close();
s.close();
}
}
---------------------------------------------------------------------
public class PicServer
{
public static voidmain(String[] args) throws Exception
{
ServerSocket ss = newServerSocket(8888);
while (true){
Socket s =ss.accept();
new Thread(newPicThread(s)).start();
}
}
}
---------------------------------------------------------------------
public class PicThread implements Runnable
{
private Socket s;
PicThread(Socket s){
this.s = s;
}
public void run(){
//获取连接成功的客户端的Ip地址
String ip = s.getInetAddress().getHostAddress();
try{
InputStream ins=s.getInputStream();
//判断文件夹下是否存在相同的文件名,存在则编号顺延
File file = newFile(ip+".jpg");
int count =1;
while(file.exists()){
file = newFile(ip+"("+(count++)+")"+",.jpg");
}
FileOutputStream os= new FileOutputStream(file);
//读取客户端发送来的数据,并写入目标文件中
byte[] bufin = newbyte[1024];
int len = 0;
while ((len =ins.read(bufin))!=-1){
os.write(bufin,0,len);
}
//向客户端发送上传成功信息
OutputStream outs =s.getOutputStream();
outs.write("Upload succeeds".getBytes());
//关闭流及对应的套接字
os.close();
s.close();
}
catch (Exception e ){
throw newRuntimeException("上传失败");
}
}
}
---------------------------------------------------------------------
Html数据响应头:
192.168.1.102is connected
GET / HTTP/1.1
Accept: */*
Accept-Language: zh-CN
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1;Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729;MDDS; .NET4.0C; Media Center PC 6.0; Tablet PC 2.0; BRI/2) QQBrowser/6.13.13461.201
Host: 192.168.1.102:9999
Connection: Keep-Alive
package cn.edward;
/ *
客户端:浏览器
服务器:自定义
* /
import java.io.*;
import java.net.*;
public class BrowserServer {
public static voidmain(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(9999);
Socket s =ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"isconnected");
InputStream ins= s.getInputStream();
byte[] buf = new byte[1024];
int len =ins.read(buf);
System.out.println(new String(buf,0,len));
PrintStream ps =new PrintStream(s.getOutputStream(),true);
ps.println("<font color='blue' size='6'>东南大学计算机</font>");
s.close();
ss.close();
}
}
--------------------------------------------------------------------------------------------------
【URL和URLConnection】:
/ *
String getFile()
获取此 URL 的文件名。
String getHost()
获取此 URL 的主机名(如果适用)。
String getPath()
获取此 URL 的路径部分。
int getPort()
获取此 URL 的端口号。
String getProtocol()
获取此 URL 的协议名称。
String getQuery()
获取此 URL 的查询部分。
* /
public class URLDemo {
public static voidmain(String[] args)throws Exception{
URL url = newURL("http://192.168.1.102:9999/myweb/myie.html?name=yun&age=22");
System.out.println(url.getFile());
System.out.println(url.getHost());
System.out.println(url.getPath());
System.out.println(url.getPort());
System.out.println(url.getProtocol());
System.out.println(url.getQuery());
}
}
对应打印结果:
/myweb/myie.html?name=yun&age=22
192.168.1.102
/myweb/myie.html
9999
http
name=yun&age=22
---------------------------------------------------------------------
将网页数据设置进文本域
String urlPath = tf.getText();
URL url = new URL(urlPath);
java.net.URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();
byte[] buf = new byte[1024*1024*64];
int len = in.read(buf);
ta.setText(newString(buf,0,len));
---------------------------------------------------------------------