Android基于socket的群聊程序
在网上看了好多,但是感觉不是太简单就是只能单独聊,所以就自己写了个可以群聊的,直接上代码了
一、服务器端
这里用的MyEclipse作为服务器端
MyServerScoket.java
package com.scme.server;
public class MyServerScoket {
public static void main(String[] args) {
new ServerListener().start();
}
}
ServerListener.java
package com.scme.server; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; import javax.swing.JOptionPane; public class ServerListener extends Thread { @Override
public void run() {
// 1-65535
try {
// 端口
ServerSocket serverScoket = new ServerSocket(12345);
while (true) {
// 阻塞当前线程
Socket socket = serverScoket.accept();
// 建立连接,控制台打印
System.out.println("有客户端连接到了本机的12345端口");
// 弹出窗口提示
JOptionPane.showMessageDialog(null, "有客户端连接到了本机的12345端口");
//将socket传递新的线程
ChatSocket cs = new ChatSocket(socket);
cs.start();
ChatManger.getChatManger().add(cs);
} } catch (IOException e) {
e.printStackTrace();
}
}
}
ChatSocket.java
package com.scme.server; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket; public class ChatSocket extends Thread { Socket socket; public ChatSocket(Socket s){
this.socket = s;
} public void out(String out){
try {
socket.getOutputStream().write((out+"\n").getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
} } @Override
public void run() {
out("你已经连接到本服务器了");
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
String line = null;
while ((line = br.readLine()) != null) {
ChatManger.getChatManger().publish(this, line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
} }
}
ChatManger.java
package com.scme.server;
import java.util.Vector;
public class ChatManger {
//单例化
private ChatManger(){}
private static final ChatManger cm = new ChatManger();
public static ChatManger getChatManger(){
return cm;
}
Vector<ChatSocket> vector = new Vector<ChatSocket>();
public void add(ChatSocket cs){
vector.add(cs);
}
public void publish(ChatSocket cs,String out){
for (int i = 0; i < vector.size(); i++) {
ChatSocket csChatSocket = vector.get(i);
if (!cs.equals(csChatSocket)) {
csChatSocket.out(out);
}
}
}
}
二、客户端
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" > <EditText
android:id="@+id/ip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:hint="输入服务器的IP地址"
android:text="10.0.2.2" > </EditText> <Button
android:id="@+id/connect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.4"
android:text="连接" /> </LinearLayout> <ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.86" > <TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Ready..." />
</ScrollView> <EditText
android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="在这里输入内容" /> <Button
android:id="@+id/send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="发送" /> </LinearLayout>
Main.java
package com.scme.aserversocket; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket; import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { private EditText ip,edit;
private TextView text; private void init() {
ip = (EditText) findViewById(R.id.ip);
edit = (EditText) findViewById(R.id.edit);
text = (TextView) findViewById(R.id.text);
findViewById(R.id.connect).setOnClickListener(this);
findViewById(R.id.send).setOnClickListener(this);
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
} Socket socket = null;
BufferedWriter writer = null;
BufferedReader reader = null; /**
* 连接
*/
public void connect(){
AsyncTask<Void, String, Void> read = new AsyncTask<Void, String, Void>(){ @Override
protected Void doInBackground(Void... params) {
try {
socket = new Socket(ip.getText().toString(), 12345);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
publishProgress("@success");
} catch (Exception e) {
Toast.makeText(MainActivity.this, "无法建立连接", 1000).show();
e.printStackTrace();
}
try {
String line;
while ((line = reader.readLine())!=null) {
publishProgress(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
} @Override
protected void onProgressUpdate(String... values) {
if (values[0].equals("@success")) {
Toast.makeText(MainActivity.this, "建立连接成功", 1000).show();
}
text.append("对方说:"+values[0]+"\n");
super.onProgressUpdate(values);
} };
read.execute();
} /**
* 发送
*/
public void send(){
try {
text.append("我说:"+edit.getText().toString()+"\n");
writer.write(edit.getText().toString()+"\n");
writer.flush();
edit.setText("");
} catch (Exception e) {
e.printStackTrace();
}
} @Override
public void onClick(View v) {
switch (v.getId()) {
//连接
case R.id.connect:
connect();
break;
//发送
case R.id.send:
send();
break;
}
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
客户端任意开。。。
还有最重要的,别忘了在主配置文件里加入网络权限啊。。。
Android基于socket的群聊程序的更多相关文章
- Android 基于Socket的聊天应用(二)
很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的 ...
- Tinychatserver: 一个简易的命令行群聊程序
这是学习网络编程后写的一个练手的小程序,可以帮助复习socket,I/O复用,非阻塞I/O等知识点. 通过回顾写的过程中遇到的问题的形式记录程序的关键点,最后给出完整程序代码. 0. 功能 编写一个简 ...
- JAVA 网络编程 - 实现 群聊 程序
在实现 这个 程序之前, 我们 需要 了解 一些 关于 Java 网络 编程 的 知识. 基本 的 网络知识: 网络模型 OSI (Open System Interconnection 开放系统互连 ...
- 基于Socket的UDP发包程序
UDP(User Datagram Protocol,用户数据报协议)是在互联网中常用的传输层协议,该协议提供了向另一用户程序发送的消息的最简便的协议机制.与TCP一样,其默认的下层协议是IP.UDP ...
- java 网络编程之UDP通信和简单的群聊程序
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- 利用TCP协议,实现基于Socket的小聊天程序(初级版)
TCP TCP (Transmission Control Protocol)属于传输层协议.其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送.可靠性.有效流控.全双工操作和多路复用 ...
- Android—基于Socket与上传图片到客户端
最近项目中需要客户端和Socket互相传递数据时候需要相互传递图片所以做下总结以免以后忘记,也希望给大家带来帮助. 先上客户端的代码: 根据图片名称上传照相机中单个照片(此方法为自己封装) 参数所代表 ...
- Android 基于Socket的聊天室(一)
Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信. Client A ...
- 基于netty的群聊
基于netty的群聊 学了一段时间的netty知识,现在通过这个基于console的程序来对netty的相关接口做个简单的应用. 准备 依赖 <dependency> <groupI ...
随机推荐
- C语言进行站点开发之cgi
安装Apach 配置ApacheRuntime 以下的过程中一直点击next 配置CGI,放开配置:AddHandler cgi-script .cgi watermark/2/text/aHR ...
- 25线程基础-CLR
由CLR via C#(第三版) ,摘抄记录... 1.线程是CPU的虚拟化,windows为每个进程提供专用线程(CPU)2.线程开销:内存和时间. 线程内核对象—OS为系统中创建的每个线程都分配并 ...
- MySQL的基本操作--第一弹
前言:在听许嵩,忆当年,意气风发 ———————————————————————————————————————————————— 好了,今天和大家同步讲解mysql的知识了.都是最基本的知识. 一. ...
- 模型层TP框架数据库的操作
在shop入口的文件下的HOME文件夹中使用模型层 第一步修改配置模块把数据库的各种链接做好,打开HOME中的conf文件夹中的config.php,找到Thinkphp文件加下的conf文件打开co ...
- fedora找开ftpd服务器并以root登陆
工作原因需要在federal中弄个vsftpd再用root去登陆(我知道这样不太安全) 确认系统的版本 [root@localhost ~]# uname -a Linux localhost.loc ...
- 九度OJ 1344:可乐瓶展览 (DP)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:430 解决:76 题目描述: 众所周知JOBDU旗下的JOBCOLA公司是文明全球的著名可乐制造商,与其它可乐公司不同的是,JOBCOLA可 ...
- [luogu4255]公主の#18文明游戏
[luogu4255]公主の#18文明游戏 luogu 发现没有连边,只有删边? 考虑倒着做 开map记M[i][j]表示编号为i的并查集,信仰j的人数 s[i]表示编号为i的并查集的总人数 首先询问 ...
- Java 线程的终止-interrupt
Java线程的终止——interrupt 取消/关闭的场景 我们知道,通过线程的start方法启动一个线程后,线程开始执行run方法,run方法运行结束后线程退出,那为什么还需要结束一个线程呢?有多种 ...
- SQL性能优化常用语句(摘录网上)
1.把trace文件导入到表中 , ) AS RowNumber,* into TableName FROM fn_trace_gettable('trace.trc', default) 2.查询C ...
- AbstractQueuedSynchronizer(一)
应该将子类定义为非公共内部帮助器类,一般并发包类用内部类Sync sync来继承并实现.为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量.事件,等等)提供一个框架.此类的设计目 ...