JAVA之socket編程服務器與客戶端通信--實現簡易聊天室

本文將介紹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();
}
}

以上就是本文所有內容,希望能幫到大家!!!

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