原生java socket通讯
server端
start.java
package server.action;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class start {
static List<User> users;
public static void main(String[] args){
final int host = 9999;
ServerSocket server = null;
try {
server = new ServerSocket(host);
} catch (IOException e) {
e.printStackTrace();
}
users = new ArrayList<>();
while(true){
System.out.println("listening...");
Socket socket = null;
try {
socket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("success");
Date day=new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// dateTime = df.format(day);
System.out.println(df.format(day));
User user = new User();
user.setSocket(socket);
user.setIp(socket.getInetAddress().getHostAddress());
// user.setUsername(getSocketName.value);
users.add(user);
System.out.println("users"+users);
System.out.println("聊天室人数"+users.size());
// createAMenber(user);
MenberThread thread = new MenberThread(user);
thread.start();
}
}
}
class MenberThread extends Thread{
private int wordslong = 128;
private User user;
public MenberThread(User user){
this.user = user;
}
@Override
public void run() {
while(true){
BufferedInputStream inputStream = null;
try {
// BufferedOutputStream tip = new BufferedOutputStream(user.getSocket().getOutputStream());
// tip.write("success".getBytes("utf-8"));
// tip.flush();
inputStream = new BufferedInputStream(this.user.getSocket().getInputStream());
}catch (Exception e){
e.printStackTrace();
}
byte[] b = new byte[wordslong];
try {
inputStream.read(b);
} catch (Exception e1) {
e1.printStackTrace();
try {
this.user.getSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.user.getUsername()+"退出(inputStream)");
System.out.println("聊天室人数"+start.users.size());
start.users.remove(this.user);
return;
// for (User user2:start.users){
// if(user2.getIp().equals(this.user.getIp())){
// System.out.println(user2);
// System.out.println("退出");
// // users.remove(i);
// start.users.remove(user2);
//// System.out.println("outputStream.flush();");
//// // System.out.println("users.remove(user2)");
//// System.out.println("users"+users);
//// break;
// System.out.println("聊天室人数"+start.users.size());
// break;
// }
// }
// return;
}
String str = null;
try {
str = new String(b, "utf-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
System.out.println(str);
if(this.user.getRole() == null){
this.user.setActivityId(str.split("&")[2]);
this.user.setRole(str.split("&")[0]);
this.user.setUsername(str.split("&")[1]);
continue;
}
//数据广播
for(int i = 0; i < start.users.size(); i++){
User user1 = start.users.get(i);
if(!this.user.getActivityId().equals(user1.getActivityId())){
continue;
}
BufferedOutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(user1.getSocket().getOutputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Date day=new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// System.out.println(df.format(day));
outputStream.write((df.format(day)+":"+user.getUsername()+"("+user.getRole()+")"+":"+str).getBytes("UTF-8"));
outputStream.flush();
System.out.println("已广播"+user1.getUsername());
} catch (Exception e1) {
e1.printStackTrace();
try {
this.user.getSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.user.getUsername()+"退出(inputStream)");
System.out.println("聊天室人数"+start.users.size());
start.users.remove(this.user);
// for (User user2:start.users){
// if(user2.getIp().equals(user.getIp())){
// System.out.println(user2);
// System.out.println("退出");
// // users.remove(i);
// start.users.remove(user2);
// // System.out.println("outputStream.flush();");
// // // System.out.println("users.remove(user2)");
// System.out.println("聊天室人数"+start.users.size());
// break;
// }
// }
//
// return;
}
}
}
}
}
class User{
private Socket socket = null;
private String username = null;
private String activityId = null;
private String ip = null;
private String role = null;
public User(){}
@Override
public String toString() {
return "User{" +
"socket=" + socket +
", username='" + username + '\'' +
", activityId='" + activityId + '\'' +
", ip='" + ip + '\'' +
", role='" + role + '\'' +
'}';
}
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
client端
start.java
package client.action;
public class start {
public static void main(String[] args) {
new initClient();
}
}
initClient.java
package client.action;
import client.util.getSocket;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.net.Socket;
import java.util.Scanner;
class initClient extends ClientWindows
{
Socket socket;
final int wordslong = 128;
String name;
initClient()
{
super();
name = JOptionPane.showInputDialog("input your name");
socket = new getSocket().getData();
receive();
Scanner read = new Scanner(System.in);
try
{
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
String tellall = name+"join in";
out.write(tellall.getBytes("utf-8"));
out.flush();
jb3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try{
String str = jare2.getText();
jare2.setText("");
str = name+"says: "+str;
out.write(str.getBytes("utf-8"));
out.flush();
}
catch(Exception e1)
{
out(e1.toString());
}
}
});
}
catch(Exception e)
{
//System.out.arintln(e.toString());
out(e.toString());
}
}
void receive(){
new Thread( new Runnable() {
public void run()
{
while(true)
{
try
{
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
byte[] b = new byte[wordslong];
in.read(b);
String str = new String(b, "utf-8");
//System.out.arintln(str);
out(str);
}
catch(Exception e)
{
//System.out.arintln(e.toString());
out(e.toString());
break;
}
}
}
}).start();
}
void out(String str)
{
jare1.append(str);
jare1.append("\n");
}
}
ClientWindows.java
package client.action;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class ClientWindows extends JFrame {
//定义组件
JPanel ja1,ja2;//定义两个面板
JButton jb1,jb2,jb3;//定义按钮
JLabel jl1,jl2;
JTextField jt1;
JTextArea jare1,jare2;
// String[] emoij = {"w(?Д?)w","(??????)??","Σ( ° △ °|||)︴","凸(艹皿艹 )","(°ー°〃)","(ˉ▽ ̄~) 切~~","┑( ̄Д  ̄)┍","━┳━ ━┳━","o( =?ω?= )m","ヽ(*。>Д<)o゜","━━( ̄ー ̄*|||━━",
// "X﹏X","⊙▽⊙","Σ(`д′*ノ)ノ","O(≧口≦)O","o(*////▽////*)q","ヾ( ̄▽ ̄)Bye~Bye~","?▽?","(?Д?*)?","( ̄▽ ̄)~■干杯□~( ̄▽ ̄)"};
String emoij = " w(?Д?)w (??????)?? Σ( ° △ °|||)︴ 凸(艹皿艹 ) (°ー°〃) (ˉ▽ ̄~) 切~~┑( ̄Д  ̄)┍ ━┳━ ━┳━ o( =?ω?= )m ヽ(*。>Д<)o゜ ━━( ̄ー ̄*|||━━ "+
"X﹏X ⊙▽⊙ Σ(`д′*ノ)ノ O(≧口≦)O o(*////▽////*)q ヾ( ̄▽ ̄)Bye~Bye~ ?▽? (?Д?*)? ( ̄▽ ̄)~■干杯□~( ̄▽ ̄) ";
//构造函数
ClientWindows(){
// ImageIcon im = new ImageIcon("timg2.gif");
// Image image = im.getImage();
// Image smallImage = image.getScaledInstance(150,400,Image.SCALE_FAST);
// ImageIcon img = new ImageIcon(smallImage);
// jl1 = new JLabel(img);
// this.add(jl1);
ja1=new JPanel();
ja2=new JPanel();
jare1 = new JTextArea(28,60);
JScrollPane scrollaane_1 = new JScrollPane(jare1);
scrollaane_1.setSize(10,10);
scrollaane_1.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//滚动条一直显示
// scrollaane_1.setVerticalScrollBarPolicy();
jare1.setEditable(false);//只读
jare1.setLineWrap(true);//行过长自动换行
jare1.setWrapStyleWord(true);//单词换行
this.add(scrollaane_1);
//jb1 = new JButton("文件");
//this.add(jb1);
jb2 = new JButton("表情");
jb2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFrame jfame = new JFrame("表情");
jfame.setSize(500,500);
jfame.setLayout(new FlowLayout());
jfame.setLocationRelativeTo(null);
jfame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
// jfame.setDefaultCloseOperation();
jfame.setResizable(false);
jfame.setVisible(true);
JTextArea jare4 = new JTextArea(30,60);
jare4.append(emoij);
// for(int i = 0;i<emoij.length;i++){
// jare4.append(emoij[i]);
//// if(i<emoij.length-1){
//// jare4.append(" ");
//// }
// }
jare4.setEditable(false);//只读
jare4.setLineWrap(true);//行过长自动换行
jare4.setWrapStyleWord(true);//单词换行
jfame.add(jare4);
}
});
this.add(jb2);
jb3 = new JButton("发送");
this.add(jb3);
add(new JLabel(" "));//添加空白标签来实现换行
jare2 = new JTextArea(10,60);//输入
JScrollPane scrollaane_2 = new JScrollPane(jare2);
scrollaane_2.setSize(10,10);
// setVerticalScrollBaraolicy
scrollaane_2.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//滚动条一直显示
jare2.setLineWrap(true);
jare2.setWrapStyleWord(true);
ja1.add(scrollaane_2);
this.add(ja1);
//设置窗口属性
this.setLayout(new FlowLayout());
this.setSize(700,700);
this.setTitle("聊天窗口");
this.setLocationRelativeTo(null);//居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setVisible(true);
}
public static void main(String[] args) {
new ClientWindows();
}
}
getSocket.java
package client.util;
import java.io.IOException;
import java.net.Socket;
/**
* @author xzy
* @create 2021/12/26 21:03
*/
public class getSocket {
Socket socket;
final String address = "192.168.56.1";
final int host = 9999;
public Socket getData(){
try {
socket = new Socket(address, host);
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
}
安卓充当client端
server端与原生一样
安卓client端代码
SocketActivity.java
package com.example.task.socket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
import com.example.task.R;
import com.example.task.adapter.AppDetailListViewBaseAdapter;
import com.example.task.bean.Recode;
import com.example.task.bean.SocketUser;
import com.example.task.sqlite.dao.RecodeDao;
public class SocketActivity extends AppCompatActivity {
//IP地址和端口号
public static String IP_ADDRESS = "106.54.189.155";
// public static String IP_ADDRESS = "192.168.51.235";
public static int PORT = 9999;
//三个控件
EditText et_message = null; //需要发送的内容
Button bt_send = null; //发送
TextView tv_reply = null; //服务器回复的消息
//handler
Handler handler = null;
Socket socket = null;
//socket连接状态
Boolean isConnect;
Boolean isReceive;
RecodeDao recodeDao;
ListView listView;
List<Map<String,Object>> lists;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_socket2);
listView = findViewById(R.id.ListView);
listView.setSelection(listView.getBottom());
recodeDao = new RecodeDao(this);
lists = new ArrayList<>();
// Button button = findViewById(R.id.Button);
// button.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// new RecodeDao(SocketActivity.this).delete();
// tv_reply.setText("");
// }
// });
Intent intent = getIntent();
//从Intent中取出Bundle
Bundle bundle = intent.getExtras();
//获取FunPerson里的数据数据
assert bundle != null;
SocketUser user = (SocketUser)bundle.getSerializable("SocketUser");
assert user != null;
et_message = findViewById(R.id.et_message);
bt_send = findViewById(R.id.bt_connect);
tv_reply = findViewById(R.id.tv_reply);
// recodeDao.delete();
//数据库加载
List<Recode> list = recodeDao.select();
for(Recode recode:list){
Map<String,Object> map = new HashMap();
String str = recode.getData();
System.out.println("str"+str);
if(str.length() <= "2022-06-28 01:59:02:李四(student):".length()){
continue;
}
String time = str.split(":")[0]+":"+str.split(":")[1]+":"+str.split(":")[2];
String role = str.split(":")[3];
String data = str.split(":")[4];
if((user.getRoleName()+"("+user.getRole()+")").equals(role)){
map.put("name2",role);
map.put("data2",data);
map.put("image2",R.drawable.img_wyu);
}else{
map.put("name1",role);
map.put("data1",data);
map.put("image1",R.drawable.img_wyu);
}
// System.out.println(time+role+data);
// map.put("time",time);
lists.add(map);
// tv_reply.append(str);
// tv_reply.append("\n");
}
if(lists.size() != 0){
AppDetailListViewBaseAdapter adapter = new AppDetailListViewBaseAdapter(lists,this);
// SimpleAdapter adapter = new SimpleAdapter(this,lists,R.layout.activity_socket_item,
// new String[]{"image1","role1","data1","role2","data2","image2"},
//// new int[]{R.id.ImageView1,R.id.name1,R.id.data1});
// new int[]{R.id.ImageView1,R.id.name1,R.id.data1,R.id.name2,R.id.data2,R.id.ImageView2});
listView.setAdapter(adapter);
listView.setSelection(listView.getBottom());
}
//todo 看这里啊喂!!!
bt_send.setOnClickListener(v -> {
new Send(et_message.getText().toString()).start();
et_message.setText("");
// System.out.println("已发送");
});
handler = new Handler(msg -> {
Bundle b = msg.getData(); //获取消息中的Bundle对象
String str = b.getString("data"); //获取键为data的字符串的值
// String time = str.split(":")[0]+":"+str.split(":")[1]+":"+str.split(":")[2];
String role = str.split(":")[3];
String data = str.split(":")[4];
Map<String,Object> map = new HashMap();
if((user.getRoleName()+"("+user.getRole()+")").equals(role)){
map.put("name2",role);
map.put("data2",data);
map.put("image2",R.drawable.img_wyu);
}else{
map.put("name1",role);
map.put("data1",data);
map.put("image1",R.drawable.img_wyu);
}
lists.add(map);
AppDetailListViewBaseAdapter adapter2 = new AppDetailListViewBaseAdapter(lists,this);
// SimpleAdapter adapter2 = new SimpleAdapter(this,lists,R.layout.activity_socket_item,
// new String[]{"image1","role1","data1","role2","data2","image2"},
//// new int[]{R.id.ImageView1,R.id.name1,R.id.data1});
// new int[]{R.id.ImageView1,R.id.name1,R.id.data1,R.id.name2,R.id.data2,R.id.ImageView2});
//// new int[]{R.id.ImageView1,R.id.name1,R.id.data1,R.id.name2,R.id.data2,R.id.ImageView2});
listView.setAdapter(adapter2);
listView.setSelection(listView.getBottom());
// tv_reply.append(str);
// tv_reply.append("\n");
return false;
});
//连接服务器
Connect connect = new Connect();
connect.start();
try {
connect.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
String roleName = user.getRoleName();
String activityId = user.getActivityId();
String role = user.getRole();
//todo 看这里啊喂
//role: 角色,用于分配不同权限,"student"和"teacher"两个值
//roleName: 用户名,用于标识聊天室的人
//activityName: 活动名称,用于分配不太聊天室
new Send(role+"&"+roleName+"&"+activityId).start();
}
class Connect extends Thread{
@Override
public void run() {
try {
socket = new Socket(IP_ADDRESS,PORT);
} catch (IOException e) {
e.printStackTrace();
}
isConnect=true;
isReceive=true;
Receive receive = new Receive(socket);
receive.start();
System.out.println("----connected success----");
}
}
class Receive extends Thread{
private InputStream inputStream=null;
Receive(Socket socket){
//初始化输入流
try {
inputStream = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (isReceive){
byte[] buffer = new byte[512];
try {
inputStream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
break;
}
String str = null;
try {
str = new String(buffer,"UTF-8").trim();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
recodeDao.add(new Recode(str));
Message msg = new Message();
Bundle b = new Bundle();
b.putString("data", str);
msg.setData(b);
System.out.println("已发送");
handler.sendMessage(msg);
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
finish();
}
}
//新建一个子线程,实现socket通信
class Send extends Thread {
String message;
public Send(String msg) {
this.message = msg;
}
@Override
public void run() {
try {
byte [] sendBuffer = null;
//可替代为接收输入框的字符串.getBytes
sendBuffer = message.getBytes("UTF-8");
OutputStream outputStream = socket.getOutputStream();
outputStream.write(sendBuffer);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onSupportActionModeFinished(@NonNull ActionMode mode) {
super.onSupportActionModeFinished(mode);
System.out.println("finish");
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 是否触发按键为back键
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
System.out.println("点击返回键");
outSocket();
return true;
} else {// 如果不是back键正常响应
return super.onKeyDown(keyCode, event);
}
}
//退出socket
public void outSocket(){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.task">
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" /> <!-- 读文件权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 使用特性 -->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Task">
<activity
android:name=".ui.ShareActivity"
android:exported="false"
android:theme="@style/Base.Theme.AppCompat.Dialog"/>
<activity
android:name=".ui.ListMyActivityPutActivity"
android:exported="false" />
<activity
android:name=".ui.ListStudentInfoActivity"
android:exported="false" />
<activity
android:name=".ui.Student_MessageActivity"
android:exported="false" />
<activity
android:name=".ui.PutActivityActivity"
android:exported="false" />
<activity
android:name=".MainActivityTeacher"
android:exported="true"
android:label="HOME"
android:theme="@style/Theme.Task.NoActionBar" />
<activity
android:name=".ui.UserActivityTeacher"
android:exported="false"
android:label="用户信息" />
<activity
android:name=".ui.Teacher_EvaluateActivity"
android:exported="false"
/>
<activity
android:name=".ui.EvaluateActivity"
android:exported="false" />
<activity
android:name=".ui.moreActivity"
android:exported="false"
android:label="敬请期待..."
android:theme="@style/Base.Theme.AppCompat.Dialog" />
<activity
android:name=".ui.UserActivity"
android:exported="false"
android:label="用户信息" />
<activity
android:name=".ui.SignUpActivity"
android:exported="false"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity
android:name=".ui.NoticesActivity"
android:exported="false"
android:label="公告" />
<activity
android:name=".ui.MenuActivity"
android:exported="false"
android:label="menu" />
<activity
android:name=".ui.FeedbackActivity"
android:exported="false"
android:label="反馈" />
<activity
android:name=".ui.MyActivityActivity"
android:exported="false"
android:label="我的活动"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity
android:name=".ui.My_historyActivity"
android:exported="false"
android:label="我的历史活动" />
<activity
android:name=".ui.All_historyActivity"
android:exported="false"
android:label="历史活动" />
<activity
android:name=".ui.CommentActivity"
android:exported="false"
android:label="评论区"
android:theme="@style/ActivityEntryAnimation"/>
<activity
android:name=".ui.QrCode.QrCodeActivity"
android:exported="false"
android:label="活动签到" />
<activity
android:name=".ui.AllActivityActivity"
android:exported="false"
android:label="全部活动" />
<activity
android:name=".ui.All_EvaluateActivity"
android:exported="false"
android:label="活动详情"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity
android:name=".ui.AllActivity_new"
android:exported="false"
android:label="全部活动"
android:theme="@style/Theme.Task.NoActionBar"/>
<activity android:name=".ui.QrCode.Callback" />
<activity
android:name=".MainActivity"
android:exported="true"
android:label="HOME"
android:theme="@style/Theme.Task.NoActionBar" />
<activity
android:name=".socket.SocketActivity"
android:exported="true"
/>
<activity
android:name=".login.LoginActivity"
android:label="登录">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>