物联网学习过程中遇到了需要PC端与Android端使用TCP协议进行通讯的问题,记录下来以便今后复习。
这里我PC端服务器使用的是C#编写的代码:
int port = 2000;//端口号 string host = "192.168.1.100";//服务器IP地址, IPAddress ip = IPAddress.Parse(host); IPEndPoint ipe = new IPEndPoint(ip, port); Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) //建立一个socket对象 //第一个参数指定地址族,枚举常用的有:AddressFamily.InterNetwork—IPV4地址,AddressFamily.InterNetworkV6—IPV6地址 //第二个参数指定Socket的类型,常用枚举有:SocketType.Stream表明是基于面向连接的流套接字,SocketType.Dgram表示是基于无连接的数据报套接字 //第三个参数指定Socket使用的协议,常用枚举有:ProtocolType.TCP—TCP协议,ProtocolType.UDP—UDP协议 s.Bind(ipe); //用socket对像的Bind()方法绑定EndPoint s.Listen(0);//用socket对像的Listen()方法开始监听,入参为int类型,等待客户端发出连接的请求,参数是指用户的连接数。超过拒绝通讯 Socket temp = s.Accept();//接受到客户端的连接,用socket对像的Accept()方法创建新的socket对像用于和请求的客户端进行通信 string recvStr = "";// byte[] recvBytes = new byte[1024]; int bytes; bytes = temp.Receive(recvBytes, recvBytes.Length, 0); recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);//从客户端接收信息 s.Close(); //通讯结束后关闭Socket
接下来是Android端客户机代码,Android端的代码比较简单,就不详解了
Socket socket = new Socket(ip,8888);//绑定端口 OutputStream out = socket.getOutputStream();//定义输出流 out.write(info.getBytes());//写数据 out.flush(); socket.close();//关闭流
需要注意的是4.0以后网络访问需要在子线程中完成,且不要忘了在AdroidManifest文件下添加网络访问权限
一个Android端为客户端,PC端为服务器的小例子,
PC端界面采用Winform,只有一个Button控件
public partial class Form1 : Form { Socket so;//定义连接的socket Socket reso;//定义数据接收与发送的socket Thread tr; bool flag = false; IPEndPoint iep;//定义端口 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { iep = new IPEndPoint(IPAddress.Parse("192.168.1.101"), 8888);//实例化端口 so = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); so.Bind(iep);//绑定端口 so.Listen(0); tr = new Thread(new ThreadStart(() => //实例化线程,使用lambda表达式 { reso = so.Accept(); flag = true; })); tr.Start(); } private void button1_Click(object sender, EventArgs e) { byte[] buff = Encoding.UTF8.GetBytes("成功"); if (flag)//判断是否客户端连接 reso.Send(buff); } }
Android端代码:
public class MainActivity extends Activity { private String info; private String ip; private EditText ed_ip; private EditText ed_Info; private Boolean flag = false; private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { String info = (String) msg.obj; ed_Info.setText(ed_Info.getText().toString() + info); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } public void init() { ed_ip = (EditText) findViewById(R.id.editText2); ed_Info = (EditText) findViewById(R.id.editText1); findViewById(R.id.button1).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { ip = ed_ip.getText().toString(); info = ed_Info.getText().toString(); Log.i("tag", "send ....."); new Thread() { public void run() { TCP(); }; }.start(); } }); } public void TCP() { Socket socket; try { int temp; socket = new Socket(ip, 8888); InputStream inputStream = socket.getInputStream(); byte[] buffer = new byte[512]; Message msg = new Message(); while ((temp = inputStream.read(buffer)) != -1) { msg.obj = new String(buffer, 0, temp); Log.i("tag", new String(buffer, 0, temp)); handler.sendMessage(msg); } socket.close(); } catch (Exception e) { // TODO: handle exception } } }