手机和电脑基于java的socket简单通信


了解手机与电脑的socket通信

  • 1.内网之间的通信:
    内网就是两者处于同一个局域网之中,不用考虑其他因素就可以实现。
    2.内网与外网之间的通信(这里推荐电脑作为服务端,手机作为用户端):
    当电脑处于外网,手机可以直接连接。
    然而由于IPv4的稀缺,导致许多家庭网络都被设置成内网,正常是不能进行跨网操作,这里分享两种方法:
    内网ip转为使用公网ip,一些运营商是可以通过沟通从而得到一个公网ip。
    利用打洞技术以达到跨网,市场上有许多软件可以通过映射端口,这里由于某些原因不给具体过程,百度找到教程

下面给出代码

1.直接通信部分代码

服务端:

//创建服务端
new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        serverSocket = new ServerSocket(端口号);
                    } catch (IOException e) {
                    	e.printStackTrace();
		    }
                    while(true){
                        try {
                            socket = serverSocket.accept();
                            if(socket != null){
                           	 //线程池
                                 new ServerThread(socket).start();
                            }
                        } catch (IOException e) {
                        	e.printStackTrace();
                        }
                    }
                }
}).start();

private class ServerThread extends Thread{
        private Socket socket;
        private DataInputStream dataInputStream = null;
        private DataOutputStream dataOutputStream = null;
        
        public ServerThread(Socket socket) {
            this.socket = socket;
            try {
                dataInputStream = new DataInputStream(socket.getInputStream());
                dataOutputStream = new DataOutputStream(socket.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        @Override
        public void run() {
            super.run();
            while (true){
                try {
                    textView.append(dataInputStream.readUTF()+"\n");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
}

客户端

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket();
                    socket.connect(new InetSocketAddress(Ip,port),2000);
                    dataInputStream = new DataInputStream(socket.getInputStream());
                    dataOutputStream = new DataOutputStream(socket.getOutputStream());
                } catch (IOException e) {
			e.printStackTrace();
                }
            }
}).start();

//发送消息
new Thread(new Runnable() {
	@Override
        public void run() {
		try {
			dataOutputStream.writeUTF(editText1.getText().toString());
		} catch (IOException e) {
			e.printStackTrace();
		 }
	}
  }).start();

完整程序代码

这里用的是使用花生壳之后的代码程序

电脑服务端:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;

public class MainServerSocket extends JFrame{

	private JTextArea textArea;
	private JScrollPane scrollPane;
 	private JButton button;
 	private ServerSocket serverSocket = null;
 	private Socket socket = null;

 	public static void main(String[] args) {
  		new MainServerSocket();
 	}
 
 	public MainServerSocket() {
  		windowBuild();
 	}
 
 	private void windowBuild() {
  		setLayout(null);
  		this.textArea = new JTextArea();
  		this.textArea.setLineWrap(true);
  		this.textArea.setEditable(false);
  		this.scrollPane = new JScrollPane(this.textArea);
  		this.button = new JButton("打开服务器");
		this.scrollPane.setBounds(50, 50, 480, 300);
  		this.button.setBounds(240, 400, 120, 40);
  		add(this.scrollPane);
  		add(this.button);
		this.button.addActionListener(new ActionListener() {
			@Override
   			public void actionPerformed(ActionEvent e) {
    				openServer();
   			}
  		});
  		setTitle("Android服务转发器");
 		setBounds(350,80,600,530);
  		setVisible(true);
  		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  	}
  	
	protected void openServer() {
  		new Thread(new Runnable() {
			@Override
   			public void run() {
    				try {
    						//内网端口
     					serverSocket = new ServerSocket(xxxx);
     					textArea.append("当前IP:"+InetAddress.getLocalHost().toString());
     					textArea.append("\t"+"端口xxxx"+"\n");
     					textArea.append("映射端口 :"+xxxxx+"\n\n\n");
     				} catch (IOException e) {
     					e.printStackTrace();
    				}
    				while(true) {
     					try {
      						socket = serverSocket.accept();
      						if(socket != null) {
       							new ServerThread(socket).start();
      						}
     					} catch (IOException e) {
      						e.printStackTrace();
     					}
     
    				}
    			}
  		}).start();
  
 	}

	private class ServerThread extends Thread{

  		private Socket socket;
        	private DataInputStream dataInputStream = null;
  		private DataOutputStream dataOutputStream = null;
        
  		public ServerThread(Socket socket) {
  			this.socket = socket;
   			try {
    				this.dataInputStream = new DataInputStream(socket.getInputStream());
    				this.dataOutputStream = new DataOutputStream(socket.getOutputStream());
   			} catch (IOException e) {
    				e.printStackTrace();
   			}
  		}
  		
  		@Override
  		public void run() {
   			super.run();
   			InetAddress address = socket.getInetAddress();
   			textArea.append(address+"用户连接"+"\n");
   			while(true) {
    				try {
     					String listen = null;
     					listen  = dataInputStream.readUTF().toString();
     				}catch (Exception e) {

				}
    			}
   		}
  	}
 }
  		

手机客户端(这里用的是android studio):
先看xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".view.SocketActivity">
    
    <TextView
        android:id="@+id/tv_sockettext"
        android:layout_width="250dp"
        android:layout_height="200dp"
        android:textColor="#000000"
        android:scrollbars="vertical"
        android:singleLine="false"
        android:ellipsize="none"
        android:maxLines="15"
        android:background="#CCCCCC"/>
    <EditText
        android:id="@+id/et_socket"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"/>
    <Button
        android:id="@+id/bt_socketgo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送"
        android:layout_margin="20dp"/>
    <EditText
        android:id="@+id/et_socketconnectip"
        android:layout_width="200dp"
        android:layout_height="30dp"
        android:background="#CCCCCC"
        android:hint="  服务器IP:"
        android:textColor="@android:color/black"
        android:gravity="center"
        android:layout_marginTop="10dp"/>
     <EditText
        android:id="@+id/et_socketconnectport"
        android:layout_width="200dp"
        android:layout_height="30dp"
        android:background="#CCCCCC"
        android:hint="  服务器port:"
        android:textColor="@android:color/black"
        android:gravity="center"
        android:layout_marginTop="10dp"/>
    <Button
        android:id="@+id/bt_socketconnect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="连接服务器"
        android:layout_margin="10dp"/>
</LinearLayout>

Activity

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Looper;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.utils.socket_view.R;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class SocketActivity extends AppCompatActivity {

    private TextView textView;
    private EditText editText1,editText2,editText3;
    private Button button1,button2;
    private DataInputStream dataInputStream = null;
    private DataOutputStream dataOutputStream = null;
    private Socket socket = null;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_socket);
        this.textView = findViewById(R.id.tv_sockettext);
        this.editText1 = findViewById(R.id.et_socket);
        this.editText2 = findViewById(R.id.et_socketconnectip);
        this.editText3 = findViewById(R.id.et_socketconnectport);
        this.button1 = findViewById(R.id.bt_socketgo);
        this.button2 = findViewById(R.id.bt_socketconnect);
        this.button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!TextUtils.isEmpty(editText2.getText()) && !TextUtils.isEmpty(editText3.getText())){
                    connectServer();
                }else{
                    Toast.makeText(SocketActivity.this, "不能为空", Toast.LENGTH_SHORT).show();
                }
            }
        });
        this.button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!TextUtils.isEmpty(editText1.getText())){
                    try {
                        if(!socket.isConnected()){
                            Toast.makeText(SocketActivity.this,"没有连接服务器",Toast.LENGTH_SHORT).show();
                            return;
                        }else {
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        dataOutputStream.writeUTF(editText1.getText().toString());
                                        editText1.setText("");
                                        textView.append("给服务器" + socket.getInetAddress().getHostName() + "发送了消息" +"\n");
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }).start();
                        }
                    }catch (Exception e) {
                        Toast.makeText(SocketActivity.this, "没有连接服务器", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });
    }
    
    private void connectServer() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket();
                    socket.connect(new InetSocketAddress(editText2.getText().toString(),Integer.parseInt(editText3.getText().toString())),2000);
                    dataInputStream = new DataInputStream(socket.getInputStream());
                    dataOutputStream = new DataOutputStream(socket.getOutputStream());
                    Looper.prepare();
                    Toast.makeText(SocketActivity.this, "SocketIP:"+socket.getInetAddress().getHostName()+"服务连接成功", Toast.LENGTH_SHORT).show();
                    Looper.loop();
                } catch (IOException e) {
                    Looper.prepare();
                    Toast.makeText(SocketActivity.this, "连接超时", Toast.LENGTH_SHORT).show();
                    Looper.loop();
                }
            }
        }).start();
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(socket != null){
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

效果

手机端
在这里插入图片描述
在这里插入图片描述

电脑端
在这里插入图片描述
在这里插入图片描述

如果内容觉得很乱,在这里说声抱歉,新手一枚~
如果觉得有用,点个赞呗~~~

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>