本文將介紹TCP和UDP兩種服務器與客戶端之間的通信協議
1、首先介紹TCP和UDP分別是什麼:TCP(Transfer Control Protocol) 是傳輸控制協議的縮寫,被稱 TCP / IP。UDP (User Datagram Protocol)是用戶數據報協議的縮寫,一個無連接的協議。
2、本文用到的socket是什麼:socket套接字提供了兩臺計算機之間的通信機制。 客戶端程序創建一個套接字,並嘗試連接服務器的套接字。
3、本文主要內容:
- 服務器端ServerSocket 對象建立方法:new ServerSocket(2000);端口號爲2000
- 服務器端Socket對象建立方法:ServerSocket對象調用accept()方法
- 利用Socket對象獲得輸入流:getInputStream()
- 利用輸入流獲得Scanner輸入對象:Scanner(s.getInputStream())
- 客戶端連接服務器方法:Socket(“127.1.1.1”,2000); 給Socket傳遞兩個參數分別是服務器的IP與端口號
- 利用Socket對象獲得輸出流:getOutputStream()
- 利用輸出流對象進行流輸出對象:PrintStream(s.getOutputStream())
一、TCP/IP協議信息的發送和接受
1、服務器一次性向客戶端發送信息
服務器service代碼:
import java.net.*;
import java.io.*;
class service
{
public static void main(String[] args)throws Exception
{
ServerSocket ss=new ServerSocket(2000);
Socket s=new Socket();
while(true)
{
s=ss.accept();
PrintStream ps=new PrintStream(s.getOutputStream());
ps.println("hello world");
}
}
}
客戶端client代碼:
import java.net.*;
import java.util.*;
class client
{
public static void main(String[] args)throws Exception
{
Socket s=new Socket("127.1.1.1",2000);
Scanner sc=new Scanner(s.getInputStream());
System.out.println(sc.nextLine());
}
}
2、服務器連續向客戶端發送數據,當鍵入quit結束信息的發送
服務器service代碼
import java.net.*;
import java.io.*;
import java.util.*;
class server
{
Socket s;
server(Socket s) throws Exception
{
this.s=s;
PrintStream ps=new PrintStream(s.getOutputStream());
Scanner sc=new Scanner(System.in);
while(sc.hasNext())
{
String str=sc.nextLine();
if(str.equals("quit"))System.exit(1);
ps.println(str);
}
}
public static void main(String[] args) throws Exception
{
ServerSocket ss=new ServerSocket(2000);
while(true)
{
new server(ss.accept());
}
}
}
客戶端client代碼
import java.net.*;
import java.io.*;
import java.util.*;
class client
{
client()
{
try{
Socket s=new Socket("127.1.1.1",2000);
Scanner sc=new Scanner(s.getInputStream());
while(sc.hasNext())
{
String str=sc.nextLine();
if (str.equals("quit"))System.exit(1);
System.out.println(str);
}
}catch(Exception e){}
}
public static void main(String[] args)
{
client sc=new client();
}
}
3、客戶端連續向服務器發送信息,鍵入quit結束髮送
服務器server代碼
import java.net.*;
import java.io.*;
import java.util.*;
class server
{
server()
{
try{
ServerSocket ss=new ServerSocket(2000);
Socket s=new Socket();
Scanner sc=new Scanner(s.getInputStream());
while(sc.hasNext())
{
s=ss.accept();
String str=sc.nextLine();
if(str.equals("quit"))System.exit(1);
System.out.println(str);
}
}catch(Exception e){}
}
public static void main(String[] args)
{
server1 sc=new server();
}
}
客戶端client代碼
import java.net.*;
import java.io.*;
import java.util.*;
class client
{
client()
{
try{
Socket s=new Socket("127.1.1.1",2000);
PrintStream ps=new PrintStream(s.getOutputStream());
Scanner sc=new Scanner(System.in);
while(sc.hasNext())
{
String str=sc.nextLine();
if (str.equals("quit"))System.exit(1);
ps.println(str);
}
}catch(Exception e){}
}
public static void main(String[] args)
{
client sc=new client();
}
}
4、服務器端與客戶端各利用兩個線程分別用於發送和接收,從而實現雙向信息接收,鍵入“exit”退出程序。
服務器service代碼
import java.io.*;
import java.util.*;
import java.net.*;
class servicereceive extends Thread
{
Socket s;
ServerSocket ss;
Scanner sc;
public void run()
{
try{
ServerSocket ss=new ServerSocket(2001);
Socket s=new Socket();
while(true)
{
s=ss.accept();
Scanner sc=new Scanner(s.getInputStream());
while(sc.hasNext())
{
String str=sc.nextLine();
if (str.equals("exit"))System.exit(1);
System.out.println("receive:"+str);
}
System.exit(1);
}
}catch(Exception e){}
}
}
class servicesend extends Thread
{
ServerSocket ss;
Socket s;
PrintStream ps;
Scanner sc;
public void run()
{
try{
ServerSocket ss=new ServerSocket(2000);
Socket s=new Socket();
Scanner sc=new Scanner(System.in);
while(true)
{
s=ss.accept();
PrintStream ps=new PrintStream(s.getOutputStream());
while(sc.hasNext()){
String str=sc.nextLine();
if(str.equals("exit"))System.exit(1);
ps.println(str);
System.out.println("send:"+str);
}
}
}catch(Exception e){}
}
}
class service
{
public static void main(String[] args) throws Exception
{
new servicereceive().start();
new servicesend().start();
}
}
客戶端client代碼
import java.io.*;
import java.util.*;
import java.net.*;
class clientreceive extends Thread
{
Socket s;
Scanner sc;
public void run()
{
try{
Socket s=new Socket("127.1.1.1",2000);
Scanner sc=new Scanner(s.getInputStream());
while(sc.hasNext())
{
String str=sc.nextLine();
if (str.equals("exit"))System.exit(1);
System.out.println("receive:"+str);
}
}catch(Exception e){}
}
}
class clientsend extends Thread
{
Socket s;
PrintStream ps;
Scanner sc;
public void run()
{
try{
Socket s=new Socket("127.1.1.1",2001);
PrintStream ps=new PrintStream(s.getOutputStream());
Scanner sc=new Scanner(System.in);
while(sc.hasNext())
{
String str=sc.nextLine();
if (str.equals("exit"))System.exit(1);
ps.println(str);
System.out.println("send:"+str);
}
}catch(Exception e){}
}
}
class client
{
public static void main(String[] args) throws Exception
{
new clientreceive().start();
new clientsend().start();
}
}
5、服務器向多個客戶端發送信息
- 帶線程的類的建立:class multitalk extends Thread
- 多線程對象的建立:multitalk(ss.accept())
- 重寫抽象方法:public void run()
服務器端代碼
import java.net.*;
import java.util.*;
import java.io.*;
class multitalk extends Thread
{
Socket s;
multitalk(Socket s){this.s=s;}
public void run()
{
try{
PrintStream ps=new PrintStream(s.getOutputStream());
Scanner sc=new Scanner(System.in);
while(sc.hasNext())
{
String str=sc.nextLine();
ps.println(str);
if(str.equals("bye")){System.exit(1);}
}
}catch(Exception e){}
}
public static void main(String[] args) throws Exception
{
ServerSocket ss=new ServerSocket(2000);
while(true){
multitalk mt=new multitalk(ss.accept());
mt.start();
}}}
客戶端代碼
import java.util.*;
import java.io.*;
import java.net.*;
class multiclient
{
multiclient()
{
try{
Socket s=new Socket("127.1.1.1",2000);
Scanner sc=new Scanner(s.getInputStream());
while(sc.hasNext())
{
String str=sc.nextLine();
System.out.println(str);
if(str.equals("bye"))System.exit(1);
}
}catch(Exception e){}
}
public static void main(String[] args)
{
new multiclient();
}
}
二、UDP協議信息的發送和接收
主要內容
- 數據報socket類對象的建立:DatagramSocket(port)
- 數據報對象的建立:DatagramPacket(b,b.length)或DatagramPacket(b,0,b.length,InetAddress.getByName(ip),port)
- 數據報socket類對象接收或發送數據報對象ds.receive(indp);ds.send(outdp);
- DatagramSocket(port)
1、服務器接收客戶端信息
服務端和客戶端公共類udpmessage
import java.net.*;
class udpmessage
{
DatagramPacket indp, outdp;
DatagramSocket ds;
byte[] b;
udpmessage(int port) throws Exception
{
ds=new DatagramSocket(port);
}
void sendmessage(String ip,int port) throws Exception
{
b=new byte[32];
String str="hello from send";
b=str.getBytes();
outdp=new DatagramPacket(b,0,b.length,InetAddress.getByName(ip),port);
ds.send(outdp);
}
void receivemessage() throws Exception
{
b=new byte[32];
while(true)
{
indp=new DatagramPacket(b,b.length);
ds.receive(indp);
System.out.println(new String(b,0,b.length));
}
}
}
發送端代碼
class sendmessage
{
public static void main(String[] args) throws Exception
{
udpmessage send=new udpmessage(4000);
send.sendmessage("127.1.1.1",2000);
}
}
接收端代碼
class receivemessage
{
public static void main(String[] args) throws Exception
{
udpmessage receive=new udpmessage(2000);
receive.receivemessage();
}
}
2、服務器端向客戶端組播信息
主要內容
- 數據報類:DatagramPacket(b,0,b.length,group,port)
- 組播類: 發送MulticastSocket() 接收MulticastSocket(port);
- 組播地址:group=InetAddress.getByName(ip);
- 加入組播組:joinGroup(group)
服務端和客戶端公共類udpmessage
import java.util.*;
import java.net.*;
class udpcast
{
InetAddress group;
MulticastSocket ss,cs;
int port=2000;
DatagramPacket indp,outdp;
udpcast(String ip) throws Exception
{
group=InetAddress.getByName(ip);
}
void send() throws Exception
{
byte[] buff;
Scanner sc =new Scanner(System.in);
ss=new MulticastSocket();
ss.joinGroup(group);
while(sc.hasNext())
{
String str=sc.nextLine();
buff=str.getBytes();
outdp=new DatagramPacket(buff,0,buff.length,group,port);
ss.send(outdp);
if(str.equals("quit"))System.exit(0);
}
}
void receive()throws Exception
{
cs=new MulticastSocket(port);
cs.joinGroup(group);
while(true)
{
byte[] buff=new byte[32];
indp=new DatagramPacket(buff,0,buff.length,group,port);
cs.receive(indp);
String str=new String(buff,0,buff.length);
System.out.println(str);
if(str.trim().equals("quit"))System.exit(0);
}
}
}
發送端
class udpcastserver
{
public static void main(String[] e) throws Exception
{
new udpcast("224.0.0.0").send();
}
}
接收端
class udpcastclient
{
public static void main(String[] e) throws Exception
{
new udpcast("224.0.0.0").receive();
}
}