android之TCP客户端编程
补充,由于这篇⽂章是⾃⼰⼊门的时候写的,随着Android系统的升级可能有发送需要在任务
中进⾏,如有问题请百度 thread
或者看下⾯链接的⽂章
吸取教训本来花了5个⼩时写完了,没想到,,,因为没点上⾯的⾃动保存查看⼀下,全没了,重新写呗
关于⽹络通信:每⼀台电脑都有⾃⼰的ip地址,每台电脑上的⽹络应⽤程序都有⾃⼰的通信端⼝,张三的电脑(ip:192.168.1.110)上有⼀个⽹络应⽤程序A(通信端⼝5000),李四的电脑(ip:192.168.1.220)上有⼀个⽹络应⽤程序B(通信端⼝8000),张三给李四发消息,⾸先你要知道李四的ip地址,向指定的ip(李四ip:192.168.1.220)发信息,信息就发到了李四的电脑。再指定⼀下发送的端⼝号(通信端⼝8000),信息就发到了李四电脑的⽹络应⽤程序B上。
TCP--⼀种⽹络通信⽅式⽽已。分为服务器(⽹络应⽤程序)和客户端(⽹络应⽤程序),TCP通信过程,⾸先打开服务器,监听⾃⼰的⽹络通信端⼝(假设为9000),打开客户端,设置好要连接的ip地址和服务器的⽹络通信端⼝(9000),这样服务器⼀旦监听到⽹络通信端⼝有连接,⼆者就建⽴了连接。
好⼀步⼀步写程序(最后有源码)
怎样建⽴⼯程就不说了,本来写好了并贴了图,⽹络⼀有问题全没了。抱怨⼀下,博客传图⽚真⿇烦。竟然不⽀持复制粘贴。各位朋友有什么⽅便的⽅法请告知。
在布局⽂件⾥加⼊两个按钮(button),⼀个控制连接,⼀个控制发送消息;四个输⼊⽂本框(edittext),⼀个填写发送的信息内容,⼀个显⽰服务器发来的消息。⼀个填写要链接的ip地址,⼀个填写要链接的端⼝号
布局代码
<RelativeLayout xmlns:android="schemas.android/apk/res/android"
xmlns:tools="schemas.android/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.wifi123.MainActivity" >以上都不⽤管的,软件⾃动⽣成的,配置界⾯的
<!--显⽰的标题:⽬标IP地址-->
<TextView
android:textSize="20dp"字体⼤⼩
android:id="@+id/IP_tv" id号
android:text="⽬标IP地址" 显⽰的内容
android:layout_width="wrap_content" 宽度随内容⽽定
android:layout_height="wrap_content" ⾼度度随内容⽽定
/>
<!--显⽰的标题:⽬标端⼝号-->
<TextView
android:textSize="20dp"
android:id="@+id/Port_tv"
android:text="⽬标端⼝号"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/IP_tv" 在<!--显⽰的标题:⽬标IP地址-->的下⾯
android:layout_marginTop="30dp" 离它上⾯那个组件(<!--显⽰的标题:⽬标IP地址-->)的距离
/>
<!-- ⽤于填写ip地址的⽂本框-->
<EditText
android:text="192.168.4.1"
android:id="@+id/ip_ET"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/IP_tv" 在<!--显⽰的标题:⽬标IP地址-->的右⾯
/>
<!-- ⽤于填写端⼝号的⽂本框-->
<EditText
android:text="8080"
android:id="@+id/Port_ET"
android:layout_width="wrap_content"
android:layout_height="wrap_content"android编程入门指南 pdf
android:layout_toRightOf="@id/Port_tv" 还是在谁谁谁的右⾯
android:layout_alignBottom="@id/Port_tv" 本元素的下边缘和某元素的的下边缘对齐
/>
<!-- ⽤于发送信息的⽂本框-->
<EditText
android:id="@+id/Send_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/Port_tv" 在某元素的下⽅
/
>
<!-- ⽤于连接的按钮-->
<Button
android:text="连接"
android:id="@+id/Connect_Bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="Connect_onClick"设置按钮的动作监听函数,其实有⼏种写法,就⽤最简单的⼀种
android:layout_below="@id/Send_ET" 在某元素的下⽅
/>
<!-- ⽤于发送信息的按钮-->
<Button
android:text="发送"
android:id="@+id/Send_Bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="Send_onClick"
android:layout_below="@id/Send_ET"
android:layout_alignParentRight="true" 贴紧⽗元素的右边缘,指的是整体的界⾯
/>
<!-- ⽤于接收信息的⽂本框-->
<EditText
android:background="@android:color/darker_gray"
android:id="@+id/Receive_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/Connect_Bt"
android:layout_alignParentBottom="true" 贴紧⽗元素的下边缘
/>
</RelativeLayout>
看看布局界⾯
接着开始编写功能程序
先做点击连接按钮就连接服务器
查看java的API⽂档,⾥⾯封装了专门⽤于TCP客户端通信的类,和⽅法
⾥⾯有⼀个类Socket (客服端),有⼀个它的构造⽅法
( address, int port)
创建⼀个流套接字并将其连接到指定 IP 地址的指定端⼝号。
意思是Socket socket = new ( address, int port) ;//创建连接地址和端⼝,就去连接指定的ip和端⼝号去了,address填ip地址,port填端⼝号只不过是⼀个类,我们打开看⼀下
那么
InetAddress ipAddress = ByName("192.168.4.1");
socket = new Socket(ipAddress, 8080);//创建连接地址和端⼝--------------就完了,客户端就去连接了
但是ip地址和端⼝被我们定死了,,,,可不好玩,我们就设置成获取ip⽂本框中的ip,端⼝号⽂本框中的端⼝号InetAddress ipAddress = Text().toString());
int port =Integer.Text().toString());//获取端⼝号
socket = new Socket(ipAddress, port);//创建连接地址和端⼝-------------------这样就好多了
但是由于在android⼏开始,不允许在主线程⾥连接服务器,所以只好让按钮点击后启动⼀个线程⾥⾯写上⾯的东西
package com.wifi123;
import java.InetAddress;
import java.Socket;
import java.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
Button ConnectButton;//定义连接按钮
Button SendButton;//定义发送按钮
EditText IPEditText;//定义ip输⼊框
EditText PortText;//定义端⼝输⼊框
EditText MsgText;//定义信息输出框
EditText RrceiveText;//定义信息输⼊框
Socket socket = null;//定义socket
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
ConnectButton = (Button) findViewById(R.id.Connect_Bt);//获得按钮对象
SendButton = (Button) findViewById(R.id.Send_Bt);//获得按钮对象
IPEditText = (EditText) findViewById(R.id.ip_ET);//获得ip⽂本框对象
PortText = (EditText) findViewById(R.id.Port_ET);//获得端⼝⽂本框按钮对象
}
public void Connect_onClick(View v) {
//启动连接线程
Connect_Thread connect_Thread = new Connect_Thread();
connect_Thread.start();
}
class Connect_Thread extends Thread//继承Thread
{
public void run()//重写run⽅法
{
try
{
if (socket == null) //如果已经连接上了,就不再执⾏连接程序
{
/
/⽤InetAddress⽅法获取ip地址
InetAddress ipAddress = Text().toString());
int port =Integer.Text().toString());//获取端⼝号
socket = new Socket(ipAddress, port);//创建连接地址和端⼝-------------------这样就好多了
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
对了需要添加两个权限,⼀个是wifi权限,⼀个是internet
然后下载到⼿机因为我的电脑的ip为192.168.1.101,所以我把192.168.4.1改了,192.168.4.1是为了做与wifi模块EPS8266通信使得然后打开⽹络调试助⼿,点击连接(可以关闭电脑防⽕墙),然后点击⼿机上的连接
好接着,连接按钮按⼀下连接,再按⼀下断开连接,并且,连接后按钮上显⽰断开,断开后按钮上显⽰连接
按钮事件改为
public void Connect_onClick(View v) {
if (isConnect == true) //标志位 = true表⽰连接
{
isConnect = false;//置为false
ConnectButton.setText("断开");//按钮上显⽰--断开
//启动连接线程
Connect_Thread connect_Thread = new Connect_Thread();
connect_Thread.start();
}
else //标志位 = false表⽰退出连接
{
isConnect = true;//置为true
ConnectButton.setText("连接");//按钮上显⽰连接
try
{
socket.close();//关闭连接
socket=null;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
你可以试⼀试了
接着写点击发送按钮把发送信息⽂本框的内容发送出去
先贴代码
public void Send_onClick(View v) {
try
{
//获取输出流
outputStream = OutputStream();
//发送数据
outputStream.Text().toString().getBytes());
/
/outputStream.write("0".getBytes());
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
看看javaAPI
所以才有了
//获取输出流
OutputStream outputStream = OutputStream();
//发送数据
outputStream.Text().toString().getBytes());
接收数据并在信息框显⽰出来
创建⼀个接收线程,在连接线程成功建⽴连接后启动接收线程
//接收线程
class Receive_Thread extends Thread
{
public void run()//重写run⽅法
{
try
{
while (true)
{
final byte[] buffer = new byte[1024];//创建接收缓冲区
inputStream = InputStream();
final int len = ad(buffer);//数据读出来,并且返回数据的长度runOnUiThread(new Runnable()//不允许其他线程直接操作组件,⽤提供的此⽅法可以{
public void run()
{
// TODO Auto-generated method stub
RrceiveEditText.setText(new String(buffer,0,len));
}
});
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论