通过Socket和多线程实现广播和客户端到客户端的通信,私聊时有离线消息。
1.服务器端
package com.gjy.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public class MyServers{
static Socket socket = null;
static Map<String,Client> clients = new HashMap<String,Client>();
static Vector<String> privateMesg = new Vector<String>();
public MyServers() throws IOException{
ServerSocket server=new ServerSocket(5678);
System.out.println("服务器已启动......");
while(true){
socket = server.accept();
Client client = new Client(socket);
String user = client.username;
clients.put(user,client);
System.out.println(client.username+"建立连接");
client.start();
sendPrivateMsg(user,null,null,null);
}
}
/**
*
* @param sender
* @param msge
* @param reciver
* @param type
* @throws IOException
*/
public static void sendMsg(String sender,String msge,String reciver,String type) throws IOException{
if(type.equals("siliao")){
paSend(sender,msge,reciver);
}else{
puSend(sender,msge,reciver);
}
}
/**
* 私聊时发送离线消息
* @param sender消息发送者
* @param msge消息
* @param reciver消息接者
* @param type消息形式(公聊或私聊)
* @throws IOException
*/
public static void sendPrivateMsg(String sender,String msge,String reciver,String type) throws IOException{
System.out.println("privatemsg");
Client client = clients.get(sender);
for(int i =0 ;i<privateMesg.size();i++){
String mString = privateMesg.get(i);
String st[] = mString.split(":");
String reciverString = st[0];
String mg = st[1]+": "+st[2];
if(reciverString.equals(sender)){
client.send(mg);
}
}
}
/**
* 私聊时发关消息
* @param sender消息发送者
* @param msge消息
* @param reciver消息接收者
* @throws IOException
*/
public static void paSend(String sender,String msge,String reciver) throws IOException{
Client msg = clients.get(reciver);
if(msg!=null){
msg.send(msge);
}else{
String mm = reciver+":"+msge;
privateMesg.add(mm);
Client client = clients.get(sender);
client.send(reciver+"不在线,你所发的消息将作为离线消息发送给对方");
}
}
/**
* 公聊时发送消息
* @param sender消息发送者
* @param msge消息
* @param reciver消息接收者
* @throws IOException
*/
public static void puSend(String sender,String msge,String reciver) throws IOException{
Set<String> set = clients.keySet();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next();
Client client = clients.get(key);
client.send(msge);
}
}
/**
* 关闭通信通道
* @param keys指定关闭某个用户的通道
* @throws IOException
*/
public static void close(String keys) throws IOException{
Client client = clients.get(keys);
if(client!=null){
client.client=null;
clients.remove(keys);
socket=null;
}
}
class Client extends Thread{
private Socket client;
private BufferedReader in;
private PrintWriter out;
private String username;
public Client(Socket c){
client=c;
try{
in=new BufferedReader(new InputStreamReader(client.getInputStream()));
out=new PrintWriter(client.getOutputStream());
username = in.readLine();
}catch(IOException e){
e.printStackTrace();
}
}
public void run(){
try {
String string="";
while(true){
string=in.readLine();
String s[] =string.split(":");
if(s.length==2){
String me = s[0];
String type = me.substring(0,6);
String reciver = me.substring(6,me.length());
String mesg =s[1];
String messString = username+"说:"+mesg;
if(mesg.equals("end")){
MyServers.close(username);
System.out.println(username+"断开连接");
break;
}else{
System.out.println("sending........");
MyServers.sendMsg(username,messString,reciver,type);
}
}
}
} catch (IOException e) {
System.out.println(username+"开始关闭连接");
try {
close(username);
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println(username+"关闭连接");
}
}
public void send(String str) throws IOException{
out.println(str);
out.flush();
}
}
public static void main(String[] args)throws IOException{
new MyServers();
}
}
2.客户端1,输入end结束通信
package com.gjy.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class MyClient01 implements Runnable{
static Socket socket = null;
static PrintWriter pw = null;
BufferedReader bufferedReader;
Client client;
private static String string = "";
public MyClient01(){
try {
socket = new Socket(InetAddress.getLocalHost(),5678);
System.out.println("建立连接,输入end结束连接");
pw = new PrintWriter(socket.getOutputStream());
pw.println("张三");
pw.flush();
client = new Client(socket);
client.start();
} catch (Exception e) {
System.out.println("连接不成功");
}
}
@Override
public void run() {
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
string = bufferedReader.readLine();
//输入end结束通信
if(string.equals("end")){
MyClient01.Close();
break;
}
if(!"".equals(string)){
//广播
pw.println(InetAddress.getLocalHost()+ ":" +string);
//私聊
//pw.println("siliao李四:"+string);
pw.flush();
}
} catch (IOException e) {
}
}
}
class Client extends Thread{
Socket client;
BufferedReader bufferedReader;
PrintWriter printWriter;
public Client (Socket socket) throws IOException{
this.client = socket;
bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
printWriter = new PrintWriter(client.getOutputStream());
}
public void run(){
String line = "" ;
try {
while(true){
if(string.equals("end")){
break;
}
line = bufferedReader.readLine();
System.out.println(line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("服务器被关闭");
}
}
}
public static void Close() throws IOException{
pw.println(InetAddress.getLocalHost() + ":" +string);
pw.flush();
socket = null;
}
public static void main(String args[]){
MyClient01 myClient01 = new MyClient01();
myClient01.run();
}
}
3.客户端2,输入end结束通信
package com.gjy.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class MyClient02 implements Runnable{
static Socket socket = null;
static PrintWriter pw = null;
BufferedReader bufferedReader;
Client client;
private static String string = "";
public MyClient02(){
try {
socket = new Socket(InetAddress.getLocalHost(),5678);
System.out.println("成功建立连接,输入end结束连接");
pw = new PrintWriter(socket.getOutputStream());
pw.println("李四");
pw.flush();
client = new Client(socket);
client.start();
} catch (Exception e) {
System.out.println("连接不成功");
}
}
@Override
public void run() {
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
string = bufferedReader.readLine();
//输入end结束通信
if(string.equals("end")){
MyClient02.Close();
break;
}
if(!"".equals(string)){
//广播
pw.println(InetAddress.getLocalHost()+ ":" +string);
//私聊
//pw.println("siliao张三"+ ":" +string);
pw.flush();
}
} catch (IOException e) {
}
}
}
class Client extends Thread{
Socket client;
BufferedReader bufferedReader;
PrintWriter printWriter;
public Client (Socket socket) throws IOException{
this.client = socket;
bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
printWriter = new PrintWriter(client.getOutputStream());
}
public void run(){
String line = "" ;
try {
while(true){
if(string.equals("end")){
break;
}
line = bufferedReader.readLine();
System.out.println(line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("服务器被关闭");
}
}
}
public static void Close() throws IOException{
pw.println(InetAddress.getLocalHost()+ ":" +string);
pw.flush();
socket = null;
}
public static void main(String args[]){
MyClient02 myClient02 = new MyClient02();
myClient02.run();
}
}
分享到:
相关推荐
当接受到客户端的connect请求时,accept函数会返回一个新的Socket用于与客户端通信。最后,通过read和write函数读写数据。 在Unity中,由于Unity主要是一个游戏开发引擎,其主要语言是C#,因此我们需要使用C#的...
4. **接受连接**:当有客户端连接时,服务器调用`Accept()`方法接收连接,并返回一个新的Socket用于与客户端通信。 ```csharp Socket clientSocket = serverSocket.Accept(); ``` 5. **读写数据**:使用`Receive()...
【标题】:用Socket实现的微博客户端(局域网通信) 在计算机网络编程中,Socket是一种基于TCP/IP协议栈的应用程序编程接口(API),用于在两台设备之间建立通信连接。本项目“用Socket实现的微博客户端”是利用...
本篇将详细讲解如何在Linux环境下利用socket实现客户端和服务端之间的通信,并且特别关注多客户端的群聊功能。 首先,理解socket的基本概念至关重要。在TCP/IP协议族中,socket是进程间通信的一种方式,它允许不同...
本示例“java socket多客户端之间通信”着重于如何利用Socket实现多个客户端通过服务器进行相互之间的消息传递,包括群发和定向发送。下面我们将深入探讨相关知识点。 1. **Socket基本概念**: Socket在Java中被...
描述: 1 采用C++语言 2 编译环境是code::blocks 3 使用的是非阻塞套接字 功能描述: 1 一个服务器对多个客户端之间进行...3 可以定向的向某个连接的客户端进行通信、同时也可以使用广播的方式向单个客户端发送数据
在本文中,我们将深入探讨如何在Win32平台上利用C++和Socket技术构建一个C/S架构的聊天应用程序,实现客户端间的群聊和私聊功能。首先,我们需要了解几个关键概念和关键技术。 1. **Win32 API**:Windows操作系统...
QTsocket及时通信服务端和客户端是基于QT框架实现的一个高效、实时的通信系统,它结合了MySQL数据库,提供了丰富的功能,如多用户群聊、添加好友、创建分组以及一对一私聊。在这个系统中,QTcpSocket是核心的通信...
当客户端连接请求到达时,服务器端会创建一个Socket对象用于与客户端通信。 - **客户端**:创建Socket,指定服务器的IP地址和端口号,发起连接请求。连接成功后,客户端和服务器端就可以通过Socket进行数据交换。 ...
在WPF应用中,我们可以利用C#语言和.NET框架的强大功能来创建Socket服务器,以便与多个客户端进行实时通信。 首先,我们要创建一个Socket服务器实例,监听特定的IP地址和端口号。这通常通过`System.Net.Sockets....
通过以上步骤,你可以在DELPHI中构建一个简单的Socket通信系统,实现客户端到服务器的连接,以及服务器对客户端的上线通知和广播通知。这只是一个基础示例,实际应用中可能需要添加更复杂的逻辑,如身份验证、数据...
10. **简单性与示例性**:尽管这个项目功能简单,仅实现了一对一的通信,但它是一个很好的学习起点,帮助开发者理解UDP Socket通信的基本原理和步骤。 通过研究和实践这个项目,开发者可以深入理解C#中的UDP Socket...
- 服务器端代码:展示如何创建`ServerSocket`,接受客户端连接,以及创建线程处理客户端通信。 - 客户端代码:展示了如何创建`Socket`,与服务器建立连接,以及如何收发消息。 - 可能还有配置文件,如服务器端的端口...
C# socket通信(免积分下载),本项目有三个部分:1、客户端(winform);2、服务端(winform);3、socket功能类库模块(其他项目也可以引用),socket类库模块功能齐全,只需调用其中方法即可,复用性较强,代码...
在这个场景中,我们讨论的是如何使用SocketClient来构建一个简单的服务端和客户端通信系统,实现类似聊天室的效果。这个系统可能涉及到的关键技术包括Socket编程、HTTP通信以及HttpClient。 首先,让我们详细了解...
本篇将深入探讨如何使用Socket实现一个简单的聊天室功能,包括服务端和客户端的代码实现。 一、Socket基础 Socket是网络通信的基本单元,它提供了进程间通信(IPC)的能力,尤其是跨越网络的进程间通信。在TCP/IP...
本项目“windows服务端+多客户端socket tcp通信”是基于Windows平台,利用Visual Studio 2013开发的一个示例,旨在实现服务端与多个客户端之间的实时通讯,类似于QQ群聊天的功能,同时还支持消息的群发和文件的二...
服务器接收到消息后广播给所有在线的客户端,各客户端收到消息后显示出来。为了处理并发的聊天消息,服务器可能需要使用多线程或异步I/O技术。 在实际应用中,TCP套接字的服务器和客户端可能会涉及更多复杂性,如...
- 当客户端连接请求到达时,服务端调用`accept()`函数接收连接,并返回一个新的套接字用于和客户端通信。 - 客户端和服务端使用`send()`和`recv()`函数进行数据发送和接收。这些函数是非阻塞的,可以设置超时或...
在提供的压缩包文件中,可能包含了实现这些功能的示例代码,包括服务器端和客户端的C#源码,开发者可以通过学习和修改这些代码来掌握Socket通信的核心技术。通过实践,不仅可以加深对Socket的理解,也能提高在实际...