socket方便了應用程序訪問通訊協議TCP/IP 。
socket是作爲通訊鏈入的端點。我們可以吧套接字看成是電話機,有了套接字,纔有了通訊的工具。我們可以吧IP地址看成是電話號碼,端口號看成是分機號。
1、基於TCP的socket編程。
java.net.ServerSocket是用來創建服務器端的套接字socket。
java.net.Socket是用來創建客戶端的套接字socket。
InetAddress(java.net.InetAddress)類:用來表示IP地址。
凡事基於TCP創建的套接字可以叫做流套接字。
服務器端相當於一個監聽器,用來監聽端口。
服務器與客服端之間的通訊都是輸入輸出流來實現的。
服務器端代碼如下:
[java] view plaincopy
import java.net.*;
import java.io.*;
class SocketTCPServer extends Thread//讓類繼承爲線程類
{
private Socket s;
SocketTCPServer(Socket s)
{
this.s = s;
}
public static void main(String []args)
{
server();
}
public void run()//這個就是線程方法了
{
try
{//當然當不想直接發送數據,就會去創建一個帶緩衝的流
OutputStream os=s.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
//os.write("my name is xuneng!".getBytes());
bos.write("my name is xuneng!".getBytes());
InputStream is=s.getInputStream();
byte [] buf =new byte[100];//別忘了加new
int len=is.read(buf);
System.out.println(new String(buf,0,len));
bos.close();
is.close();
os.close();
s.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void server()//完成之後一定要記得關閉各種流於套接字
{
try
{
ServerSocket ss = new ServerSocket(8000);//自定義的一個端口
while(true)//服務器端會老這樣啓動着。
{
System.out.println("the server is starting .......");
Socket s=ss.accept(); //一直等待着接收消息
new SocketTCPServer(s).start();//當接受到請求的時候,就返回一個套接字,創建一個線程
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
客戶端代碼如下:
[java] view plaincopy
import java.net.*;
import java.io.*;
class SocketTCPClient
{
private Socket s;
SocketTCPClient(Socket s)
{
this.s = s;
}
public static void main(String []args)
{
client();
}
public static void client()
{
try
{
Socket s = new Socket(InetAddress.getByName("localhost"),8000);//端口號要一致。
OutputStream os = s.getOutputStream();
os.write("Hello World!".getBytes());
InputStream is = s.getInputStream();
byte [] buf = new byte[100];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
os.close();
is.close();
s.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
2、基於UDP的socket編程。
創建流程如下:
java.net.DatagramSocket(數據電報套接字)。
java.net.DatagramPacket(數據電報包,裏面包含了發送的信息)。
基於UDP的套接字就是數據報套接字。
兩個都要先構造好相應的數據包。
在DatagramPacket包中的函數 intgetLength()返回實際接受的字節數, byte[]getData()返回接受到的數據。
要想接受端給發送端回信息,就需要知道發送端的IP地址InetAddress getAddress()和發送端進程所綁定的端口號int getPort()。
數據報套接字發送成功之後,就相當於建立了一個虛連接,雙方可以發送數據。
發送端代碼如下:
[java] view plaincopy
import java.net.*;
import java.io.*;
/*
*發送端, 相當於客戶端。
*/
class SocketUDPSend
{
public static void main(String[]args)
{
sed();
}
public static void sed()
{
try
{
DatagramSocket ds = new DatagramSocket();
String str = "haha, my name is xuneng!";
DatagramPacket dp = new DatagramPacket(str.getBytes(),0,str.length(),
InetAddress.getByName("localhost"),8600);//發送給本機的地址,端口爲8600
ds.send(dp);
//演示接受返回回來的數據。
byte[] buf = new byte[100];
DatagramPacket dp2 = new DatagramPacket(buf,100);//字節數組,長度
ds.receive(dp2);
System.out.println(new String(buf,0,dp2.getLength()));
ds.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
接收代碼如下:
[java] view plaincopy
import java.net.*;
import java.io.*;
/*
*接受端,也就是服務器端。一直在監聽端口。
*/
class SocketUDPRecv
{
public static void main(String[]args)
{
recv();
}
public static void recv()
{
try
{
DatagramSocket ds = new DatagramSocket(8600);
byte [] buf = new byte[100];
DatagramPacket dp = new DatagramPacket(buf,100);
ds.receive(dp);
System.out.println(new String(buf,0,dp.getLength()));
//演示給發送端返回數據,需要發送端去接受
String str = "Yes , I received!";
DatagramPacket dp1 = new DatagramPacket(str.getBytes(),str.length(),
dp.getAddress(),dp.getPort());
ds.send(dp1);
ds.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}