網絡編程 TCP、UDP、文本轉化器、上傳文本等練習


UDP  面向無連接  有兩端
    將數據及源和目的封裝成數據包中,不需要建立連接
    每個數據的大小在限制在64K內
    因無連接,是不可靠協議
    不需要建立連接,速度快
   
    TCP
    建立連接,形成傳輸數據的通道
    在連接中進行大數據量傳輸
    通過三次握手完成連接,是可靠協議
    必須建立連接,效率會稍低
   
    Socket   插座 
    Socket就是爲網絡服務提供的一種機制。
    通信的兩端都有Socket。
    網絡通信其實就是Socket間的通信。
    數據在兩個Socket間通過IO傳輸


------TCP練習

package day23;


/*
演示tcp的傳輸的客戶端和服務端的互訪。


需求:客戶端給服務端發送數據,服務端收到後,給客戶端反饋信息。


首先啓動服務端Server  然後啓動客戶端Client  


客戶端:
1,建立socket服務。指定要連接主機和端口。
2,獲取socket流中的輸出流。將數據寫到該流中。通過網絡發送到給服務端。
3,獲取socket流中的輸入流,將服務端反饋的數據獲取到,並打印。
4,關閉客戶端資源。


*/
import java.io.*;
import java.net.*;


class TcpClient2
{
public static void main(String[] args) throws IOException 
{
Socket s = new Socket("10.210.130.98",10004);

OutputStream out = s.getOutputStream();

out.write("服務端,你好".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 IOException
{
ServerSocket ss = new ServerSocket(10004);

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));

OutputStream out = s.getOutputStream();

out.write("哥們收到,你也好".getBytes());

s.close();

ss.close();
}


}

-------UDP 練習

package day23;

/*
需求:通過udp傳輸方式,將一段文字數據發送出去。
思路:
1,建立udpsocket服務。
2,提供數據,並將數據封裝到數據包中。
3,通過socket服務的發送功能,將數據包發送出去。
4,關閉資源。


public class DatagramSocket
extends Object此類表示用來發送和接收數據報包的套接字。 


數據報套接字是包投遞服務的發送或接收點。每個在數據報套接字上發送或接收的包都是單獨編址和路由的。
從一臺機器發送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。 


在 DatagramSocket 上總是啓用 UDP 廣播發送。爲了接收廣播包,應該將 DatagramSocket 綁定到通配符地址。
在某些實現中,將 DatagramSocket 綁定到一個更加具體的地址時廣播包也可以被接收。 


示例:DatagramSocket s = new DatagramSocket(null); 
s.bind(new InetSocketAddress(8888)); 
這等價於:DatagramSocket s = new DatagramSocket(8888); 
兩個例子都能創建能夠在 UDP 8888 端口上接收廣播的 DatagramSocket。 
*/


import java.io.IOException;
import java.net.*;

public class UDPDemo {


/**
* @param args
* throws UnknownHostException
* @throws IOException 
*/
public static void main(String[] args) throws IOException {
//1,創建udp服務。通過DatagramSocket對象。

DatagramSocket ds = new DatagramSocket();


//2,確定數據並封裝成數據包。
byte[] buf = "udp ge men lai le".getBytes();
//數據 字符串數據
//DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 
        //構造數據報包,用來將長度爲 length 偏移量爲 offset 的包發送到指定主機上的指定端口號。
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("10.210.130.98"), 10000);

//3,通過socket服務,將已有的數據包發送出去。通過send方法。
ds.send(dp);
//4,關閉資源
ds.close();
}


}


/*
需求:
定義一個應用程序,用於接收usp協議傳輸的數據並處理。


定義udp的接收端


思路:
1,定義udpsocket服務。 通常會監聽一個端口。其實就是給這個接收網絡應用程序定義數字標識。
方便於明確那些數據過來該應用程序可以處理。

2,定義一個數據包,因爲要存儲接收到的字節數據。
因爲數據包對象中有更多功能可以提取字節數據中的不同數據信息。
3,通過socket服務的receive方法將受到的數據存入已定義好的數據包中。
4,通過數據包對象的特有功能。將這些不同的數據取出。打印在控制檯上。
5,關閉資源。


DatagramPacket 類


方法摘要
--  返回值InetAddress  函數 getAddress() 
          返回某臺機器的 IP 地址,此數據報將要發往該機器或者是從該機器接收到的。
          
     byte[] getData() 返回數據緩衝區。  
     int getLength()  返回將要發送或接收到的數據的長度。      
 
類InetAddress
-- 返回值String  方法getHostAddress() 
           返回 IP 地址字符串(以文本表現形式)。 

*/


class UDPRece {

public static void main(String[] args) throws IOException {
//1,創建udp socket ,建立站點。
DatagramSocket ds = new DatagramSocket(10000);

//2,定義數據包。用於存儲數據。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);

//3,通過服務的receive方法將收到的數據存入數據包中。
ds.receive(dp);
//阻塞時方法,沒數據就等

//4,通過數據包的方法獲取其中的數據
String ip = dp.getAddress().getHostAddress();

String data = new String(dp.getData(),0,dp.getLength());

int port = dp.getPort();

System.out.println(ip+"::"+data+"::"+port);
//5,關閉資源
ds.close();
}
}

---------文本轉化器

package day23;


/*
需求:建立一個文本轉化服務器。
客戶端給服務端發送文本,服務單會將文本轉換成大寫返回給客戶端。
而且客戶端可以不斷的進行文本轉換,當客戶端輸入over時,轉換結束。


分析:
客戶端:
既然是操作設備上的數據,那麼久可以使用io技術,並按照io的操作規律來思考。
源:鍵盤錄入。
目的:網絡設備,網絡輸出流。
而且操作的是文本數據。可以選擇字符流。


步驟:
1,建立服務。
2,獲取鍵盤錄入。
3,將數據發給服務端。
4,去服務端返回的大寫數據。
5,結束,關資源。


都是文本數據,可以使用字符流進行操作,同時提高效率,加入緩衝。


*/


import java.io.*;
import java.net.*;


class TransClient
{
public static void main(String[] args) throws UnknownHostException, IOException
{
Socket s = new Socket("10.210.130.98",10005);

BufferedReader bufr = 
new BufferedReader(new InputStreamReader(System.in));
//定義目的,將數據寫入到socket輸出流。發給服務端。
BufferedWriter bufOut = 
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

//定義一個socket讀取流,讀取服務端返回大寫信息。
BufferedReader bufIn = 
new BufferedReader(new InputStreamReader(s.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("server:"+str);
}

}
}
/*
服務端:
源:socket讀取流。
目的:socket輸出流。
都是文本,裝飾。
*/
class TransServer
{
public static void main(String[] args) throws IOException{
ServerSocket ss = new ServerSocket(10005);

Socket s = ss.accept();

//讀取socket讀取流中的數據。
BufferedReader bufIn = 
new BufferedReader(new InputStreamReader(s.getInputStream()));
//目的。socket輸出流。將大寫數據寫入到socket輸出流,併發送給客戶端。
//用一個BufferedWriter寫出流 寫出去。
//BufferedWriter bufOut = 
//new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);

String line = null;
while((line=bufIn.readLine())!=null)
{
out.println(line.toUpperCase());
//bufOut.write(line.toUpperCase());
//bufOut.newLine();
//bufOut.flush();

}

s.close();
ss.close();
}
}


/*
該例子出現的問題。
現象:客戶端和服務端都在莫名的等待。
爲什麼呢?
因爲客戶端和服務端都有阻塞時的方法。這些方法麼沒有讀到結束標記。那麼久一直等
而導致兩端都在等待。




*/
public class TransTextDemo {

public static void main(String[] args) {

}


}

------複製上傳文本

package day23;


/*
 public class Socket
 extends Object
 此類實現客戶端套接字(也可以就叫“套接字”)。套接字是兩臺機器之間的通信端點。 


套接字的實際工作由 SocketImpl 類的實例執行。
應用程序通過更改創建套接字實現的套接字工廠可以配置它自身,以創建適合本地防火牆的套接字。


 void shutdownInput() 
                 此套接字的輸入流置於“流的末尾”。 


 void shutdownOutput() 
                 禁用此套接字的輸出流。 
      --其實就是在流中加入結束標記了。
      


*/
import java.io.*;
import java.net.*;


class TextClient
{
public static void main(String[] args) throws UnknownHostException, IOException
{
Socket s = new Socket("10.210.130.98",1006);

BufferedReader bufr =
new BufferedReader(new FileReader("IPDemo.java"));

PrintWriter out = new PrintWriter(s.getOutputStream());

//時間戳是唯一的  可以使用DataOutputStream操作基本數據的流對象。
//發送年齡,姓名等基本數據最方便。
//DataOutputStream dos = new DataOutputStream(s.getOutputStream());
//long time = System.currentTimeMillis();
//out.println(time);
//dos.writeLong(time);

String line = null;

while((line=bufr.readLine())!=null)
{
out.println(line);
}

s.shutdownOutput();//關閉客戶端的輸出流。相當於給流中加入一個結束標記-1.


//out.println("over");
//兩個時間戳相同
//dos.writeLong(time);

BufferedReader bufIn =
new BufferedReader(new InputStreamReader(s.getInputStream()));

String str = bufIn.readLine();
System.out.println(str);

bufr.close();

s.close();
}
}


class TextServer
{
public static void main(String[] args) throws IOException
{
ServerSocket ss = new ServerSocket(10006);

Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....connected");

//DataInputStream dis = new DataInputStream(s.getInputStream());
//結束標記
//long l = dis.readLong();

BufferedReader bufIn = 
new BufferedReader(new InputStreamReader(s.getInputStream()));

PrintWriter out = new PrintWriter(new FileWriter("server.txt"),true);
String line = null;
while((line=bufIn.readLine())!= null)
{
//if("over".equals(line))
//break;
out.println(line);
}

PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上傳成功!");

out.close();
s.close();
ss.close();

}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章