TCP通信,需要3次链接。为了更清楚明了的说明白这3次链接,我记得从网上看见过一段话,但是网址忘记了,凭借回忆以及自己的理解下来,希望能帮助到你
主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;
主机B向主机A发送同意连接和要求同步
(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:
“可以,你什么时候发?”,这是第二次对话;
主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。
如此以来,咱们就理解了这3次对话的,其实要是再说深点我也不会了。。。但是目前来说,这样理解足够使用
直接上客户端的代码,大家看看,也有注释,写的挺清楚的。
本例子实现了如下几个功能:
1,socket的通信(接受和发送)
2,异步更新UI
package com.example.socket;
import com.example.b.R;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class tcpclient extends Activity
{
// 声明对象
private Button mInButton, mSendButton;
private EditText mEditText01, mEditText02;
private static final String SERVERIP = "XXXXXXXXXXXXX";
private static final int SERVERPORT = 8888;
private Thread mThread = null;
private Socket mSocket = null;
private BufferedReader mBufferedReader = null;
private PrintWriter mPrintWriter = null;
private String mStrMSG = "";
private static String TAG = "Zhou";
//
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.myinternet_tcpclient);
mInButton = (Button) findViewById(R.id.myinternet_tcpclient_BtnIn);
mSendButton = (Button) findViewById(R.id.myinternet_tcpclient_BtnSend);
mEditText01 = (EditText) findViewById(R.id.myinternet_tcpclient_EditText01);
mEditText02 = (EditText) findViewById(R.id.myinternet_tcpclient_EditText02);
//
// 登陆
mInButton.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
try
{
// ①Socket实例化,连接服务器
mSocket = new Socket(SERVERIP, SERVERPORT);
// ②获取Socket输入输出流进行读写操作
mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);
} catch (Exception e)
{
// TODO: handle exception
Log.e(TAG, e.toString());
}
}
});
//
// 发送消息
mSendButton.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
try
{
// 取得编辑框中我们输入的内容
String str = mEditText02.getText().toString() + "\n";
// 发送给服务器
mPrintWriter.print(str);
mPrintWriter.flush();
} catch (Exception e)
{
// TODO: handle exception
Log.e(TAG, e.toString());
}
}
});
mThread = new Thread(mRunnable);
mThread.start();
}
//
// 线程:监听服务器发来的消息
private Runnable mRunnable = new Runnable()
{
public void run()
{
while (true)
{
try
{
if ((mStrMSG = mBufferedReader.readLine()) != null)
{
mStrMSG += "\n";// 消息换行
mHandler.sendMessage(mHandler.obtainMessage());// 发送消息
}
} catch (Exception e)
{
Log.e(TAG, e.toString());
}
}
}
};
//
Handler mHandler = new Handler()//更新界面的显示(不能直接在线程中更新视图,因为Android线程是安全的)
{
public void handleMessage(Message msg)
{
super.handleMessage(msg);
// 刷新
try
{
mEditText01.append(mStrMSG);// 将聊天记录添加进来
} catch (Exception e)
{
Log.e(TAG, e.toString());
}
}
};
//
}
有点问题必须要说一下,我这个贴出来以后,很多朋友给我发私信,可能是新手朋友,集中有如下几个问题
1,怎么进行数据的交互?
服务器端得到的Socket对象才用getOutputStream()方法得到输出流,等同于客户端的socket对象使用getInputStream()方法获得那个输入流
服务器端得到的Socket对象使用getInputStream()方法得到的输入流,等同于客户端Socket对象使用getOutputStream方法获得的那个输出流。
也就是说,当服务器向输入流写入信息的时候,客户端就可以通过对应的输出流得到消息从而读取。反之亦然
注:以下内容为转载(http://blog.csdn.net/maoxiao1229/article/details/22886337)在此感谢前辈的努力
3.1基于TCP协议的Socket
服务器端首先声明一个ServerSocket对象并且指定端口号,然后调用Serversocket的accept()方法接收客户端的数据。accept()方法在没有数据进行接收的处于堵塞状态。(Socketsocket=serversocket.accept()),一旦接收到数据,通过inputstream读取接收的数据。
客户端创建一个Socket对象,指定服务器端的ip地址和端口号(Socketsocket=newSocket("172.168.10.108",8080);),通过inputstream读取数据,获取服务器发出的数据(OutputStreamoutputstream=socket.getOutputStream()),最后将要发送的数据写入到outputstream即可进行TCP协议的socket数据传输。
3.2基于UDP协议的数据传输
服务器端首先创建一个DatagramSocket对象,并且指点监听的端口。接下来创建一个空的DatagramSocket对象用于接收数据(bytedata[]=newbyte[1024;]DatagramSocketpacket=newDatagramSocket(data,data.length)),使用DatagramSocket的receive方法接收客户端发送的数据,receive()与serversocket的accepet()类似,在没有数据进行接收的处于堵塞状态。
客户端也创建个DatagramSocket对象,并且指点监听的端口。接下来创建一个InetAddress对象,这个对象类似与一个网络的发送地址(InetAddressserveraddress=InetAddress.getByName("172.168.1.120")).定义要发送的一个字符串,创建一个DatagramPacket对象,并制定要讲这个数据报包发送到网络的那个地址以及端口号,最后使用DatagramSocket的对象的send()发送数据。*(Stringstr="hello";bytedata[]=str.getByte();DatagramPacketpacket=new DatagramPacket(data,data.length,serveraddress,4567);socket.send(packet);)