개인 채 팅 과 단체 채 팅 기능 을 실현 한 메 신 저.
우선 우리 가 생각 한 것 은 소식 이 왔 다 는 것 이다. 내 가 어떻게 공적 인 소식 인지, 아니면 사적인 소식 인지 알 겠 는가?그래서 여기 서 정 보 를 처리 해 야 합 니 다. 예 를 들 어 메시지 전후 에 특수 한 문 자 를 추가 하고 우 리 는 협의 문자 라 고 부 릅 니 다.이 를 위해, 우 리 는 프로 토 콜 문 자 를 정의 하기 위해 인 터 페 이 스 를 정의 할 수 있다.
두 번 째 문 제 는 개인 적 인 대화 정보 라면 클 라 이언 트 가 목적 사용자 (개인 적 인 대화 대상) 를 서버 에 보 내 는 것 이다. 그러면 서버 측은 어떻게 그 목적 의 사용 자 를 찾 을 수 있 을 까?여기 서 분명 한 것 은 사용자 와 Socket 의 매 핑 관 계 를 구축 해 야 하기 때문에 우 리 는 map 를 사 용 했 습 니 다. 그러나 이곳 의 map 는 개선 이 필요 합 니 다. 사실 우 리 는 key 가 중복 되 지 않 을 뿐만 아니 라 value 도 중복 되 지 않 습 니 다. 우 리 는 value 를 통 해 key 를 찾 을 수 있 기 때문에 개선 을 했 습 니 다.
그리고 본 실현 에 대해 지적 해 야 할 것 은 서버 서브 스 레 드 가 메 시 지 를 수신 하고 보 내 는 것 입 니 다. 이 안에 클 라 이언 트 가 처음으로 연결 을 만 들 었 을 때 사용자 이름 이 중복 되 는 지 판단 해 야 합 니 다. 즉, key 가 중복 되 지 않도록 해 야 합 니 다. 이에 대응 하려 면 클 라 이언 트 가 처음으로 연결 을 만 들 었 을 때 끊 임 없 는 시 도 를 해 야 합 니 다.제 공 된 이름 이 중복 되 지 않 을 때 까지
코드 는 다음 과 같 습 니 다:
public interface CrazyitProtocol {
public static final int PROTOCOL_LEN=2; // public static final,
public static final String MSG_ROUND="△▽";
public static final String USR_ROUND="□☆";
public static final String LOGIN_SUCCESS="☆▷";
public static final String NAME_REP="-1";
public static final String PRAVITE_ROUND="◆★";
public static final String SPLIT_SIGN="☀";
}
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class CrazyitMap extends HashMap {
// value
public void removeByValue(Object value)
{
for(Object key :keySet())
{
if(get(key)==value||get(key).equals(value))
{
remove(key);
break;
}
}
}
// value
public Set valueSet()
{
Set result=new HashSet();
for(Object key : keySet())
{
result.add(get(key));
}
return result;
}
// HashMap put , value
public V put(K key,V value)
{
for(V val : valueSet())
{
if(val==value||val.equals(value))
{
throw new RuntimeException("MyMap value");
}
}
return super.put(key, value);
}
// value key
public K getKeyByValue(Object value)
{
for(K key : keySet())
{
if(get(key)==value||get(key).equals(value))
{
return key;
}
}
return null;
}
}
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static final int PORT=30000;
public static CrazyitMap clients=new CrazyitMap<>();
void init()
{
try (
ServerSocket ss=new ServerSocket(PORT);
)
{
while(true)
{
Socket s=ss.accept();
new Thread(new ServerThread(s)).start();
}
}catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(" , ?");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Server s=new Server();
s.init();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class ServerThread implements Runnable {
private Socket s;
private BufferedReader br=null;
private PrintStream ps=null;
public ServerThread(Socket s)
{
this.s=s;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
ps=new PrintStream(s.getOutputStream());
String content=null;
while((content=br.readLine())!=null)
{
if(content.startsWith(CrazyitProtocol.USR_ROUND) //
&&content.startsWith(CrazyitProtocol.USR_ROUND))
{
String userName=getRealMsg(content);
if(Server.clients.containsKey(userName)) //
{
System.out.println(" ");
ps.println(CrazyitProtocol.NAME_REP);
}
else //
{
System.out.println(" ");
Server.clients.put(userName, ps);
ps.println(CrazyitProtocol.LOGIN_SUCCESS);
}
}
else if(content.startsWith(CrazyitProtocol.PRAVITE_ROUND)
&&content.startsWith(CrazyitProtocol.PRAVITE_ROUND))// ,
{
String userAndMsg=getRealMsg(content);
String userName=userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[0];
String Msg=userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[1];
//
Server.clients.get(userName).println(Server.clients.getKeyByValue(ps)
+" "+Msg);
}
else //
{
String Msg=getRealMsg(content);
for(PrintStream ps : Server.clients.valueSet())
{
ps.println(Server.clients.getKeyByValue(this.ps)
+" :"+Msg);
}
}
}
}
// , Socket ,
// Map
catch (IOException e) {
// TODO Auto-generated catch block
Server.clients.removeByValue(ps);
try{
if(br!=null)
{
br.close();
}
if(ps!=null)
{
ps.close();
}
if(s!=null)
{
s.close();
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
// ,
private String getRealMsg(String content) {
// TODO Auto-generated method stub
return content.substring(CrazyitProtocol.PROTOCOL_LEN,
content.length()-CrazyitProtocol.PROTOCOL_LEN);
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JOptionPane;
public class Client {
private static final int PORT=30000;
private Socket s=null;
private PrintStream ps=null;
private BufferedReader brServer=null; //
private BufferedReader keyIn=null; //
public void init()
{
try
{
s=new Socket("127.0.0.1",PORT);
ps=new PrintStream(s.getOutputStream());
keyIn=new BufferedReader(new InputStreamReader(System.in));
brServer=new BufferedReader(new InputStreamReader(s.getInputStream()));
// ,
String tip="";
while(true)
{
String userName=JOptionPane.showInputDialog(tip
+" ");
//
ps.println(CrazyitProtocol.USR_ROUND+userName
+CrazyitProtocol.USR_ROUND);
String result=brServer.readLine();
if(result.equals(CrazyitProtocol.NAME_REP))
{
tip=" , ";
continue;
}
//
if(result.equals(CrazyitProtocol.LOGIN_SUCCESS))
{
break;
}
}
}
catch(UnknownHostException ex)
{
System.out.println(" , !");
closeRs();
System.exit(1);
}
catch(IOException ex)
{
System.out.println(" ! !");
closeRs();
System.exit(1);
}
new Thread(new ClientThread(brServer)); //
}
private void closeRs() {
// TODO Auto-generated method stub
try{
if(keyIn!=null)
{
keyIn.close();
}
if(brServer!=null)
{
brServer.close();
}
if(ps!=null)
{
ps.close();
}
if(s!=null)
{
s.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
//
public void readAndSend()
{
String content=null;
try
{
while((content=keyIn.readLine())!=null)
{
// / , :
if(content.startsWith("/")&&content.indexOf(":")>0)
{
content=content.substring(1); // /
content=CrazyitProtocol.PRAVITE_ROUND+content.split(":")[0]+CrazyitProtocol.SPLIT_SIGN
+content.split(":")[1]+CrazyitProtocol.PRAVITE_ROUND;
ps.println(content);
}
else //
{
content=CrazyitProtocol.MSG_ROUND+content+CrazyitProtocol.MSG_ROUND;
ps.println(content);
}
}
}
catch(IOException e)
{
System.out.println(" ! !");
closeRs();
System.exit(1);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Client client=new Client();
client.init();
client.readAndSend();
}
}
import java.io.BufferedReader;
import java.io.IOException;
public class ClientThread implements Runnable {
private BufferedReader brServer=null;
public ClientThread(BufferedReader brServer)
{
this.brServer=brServer;
}
@Override
public void run() {
// TODO Auto-generated method stub
String content=null;
try
{
while((content=brServer.readLine())!=null)
{
System.out.println(content);
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try{
if(brServer!=null)
{
brServer.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
참고 자료: JAVA 광란 강의
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.