1、Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。 Socket建立为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符
2、的句柄。socket函数原型为:int socket(int domain, int type, int protocol);domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族);type参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值0。Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。 Socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用Socket函数时,socket
3、执行体将建立一个Socket,实际上建立一个Socket意味着为一个Socket数据结构分配存储空间。 Socket执行体为你管理描述符表。两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。Socket数据结构中包含这五种信息。 Socket在测量软件中的使用也很广泛。2.实验步骤本实验在Visual Studio 2010以及安卓模拟器下实现,项目包括安卓客户端源码和服务端C#源码,本机ip为127.0.0.1,实验要实现客户端与服务端在4567号端口的通信,具体代码如下:服务端核心代码:using System;using Sys
4、tem.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Collections;using System.Net;using System.Net.Sockets;using System.Threading;namespace MySocketServer public partial class FormServer
5、 : Form public FormServer() InitializeComponent(); /保存与客户相关的信息列表 ArrayList friends = new ArrayList(); /负责监听的套接字 TcpListener listener; /只是是否启动了监听 bool IsStart = false; /对控件进行调用委托类型和委托方法 /在列表中写字符串 delegate void AppendDelegate(string str); AppendDelegate AppendString; /在建立列表时,向下拉列表中添加客户信息 delegate void
6、 AddDelegate(MyFriend frd); AddDelegate Addfriend; /在断开连接时,从下拉列表中删除客户信息 delegate void RemoveDelegate(MyFriend frd); RemoveDelegate Removefriend; /在列表中写字符串的委托方法 private void AppendMethod(string str) listBoxStatu.Items.Add(str); listBoxStatu.SelectedIndex = listBoxStatu.Items.Count - 1; listBoxStatu.C
7、learSelected(); /向下拉列表中添加信息的委托方法 private void AddMethod(MyFriend frd) lock (friends) friends.Add(frd); comboBoxClient.Items.Add(frd.socket.RemoteEndPoint.ToString(); /从下拉列表中删除信息的委托方法 private void RemoveMethod(MyFriend frd) int i = friends.IndexOf(frd); comboBoxClient.Items.RemoveAt(i); friends.Remov
8、e(frd); frd.Dispose(); private void FormServer_Load(object sender, EventArgs e) /实例化委托对象,与委托方法关联 AppendString = new AppendDelegate(AppendMethod); Addfriend = new AddDelegate(AddMethod); Removefriend = new RemoveDelegate(RemoveMethod); /获取本机IPv4地址 List listIP = getIP(); if (listIP.Count = 0) boBoxIP.
9、Items.Clear(); boBoxIP.Text = 未能获取IP!; else if (listIP.Count = 1) boBoxIP.Items.Add(listIP0); boBoxIP.SelectedIndex = 0; else foreach (string str in listIP) boBoxIP.Items.Add(str);请选择IP! /设置默认端口号 textBoxServerPort.Text = 4567 private void buttonStart_Click(object sender, EventArgs e) /服务器已在其中监听,则返回
10、if (IsStart) return; /服务器启动侦听 IPEndPoint localep = new IPEndPoint(IPAddress.Parse(comboBoxIP.Text), int.Parse(textBoxServerPort.Text); listener = new TcpListener(localep); listener.Start(10); IsStart = true; listBoxStatu.Invoke(AppendString, string.Format(服务器已经启动监听!端点为:0。, listener.LocalEndpoint.ToS
11、tring(); /接受连接请求的异步调用 AsyncCallback callback = new AsyncCallback(AcceptCallBack); listener.BeginAcceptSocket(callback, listener); this.buttonStart.Enabled = false; private void AcceptCallBack(IAsyncResult ar) try /完成异步接收连接请求的异步调用 /将连接信息添加到列表和下拉列表中 Socket handle = listener.EndAcceptSocket(ar); MyFrie
12、nd frd = new MyFriend(handle); comboBoxClient.Invoke(Addfriend, frd); AsyncCallback callback; /继续调用异步方法接收连接请求 callback = new AsyncCallback(AcceptCallBack); /开始在连接上进行异步的数据接收 frd.ClearBuffer(); callback = new AsyncCallback(ReceiveCallback); frd.socket.BeginReceive(frd.Rcvbuffer, 0, frd.Rcvbuffer.Lengt
13、h, SocketFlags.None, callback, frd); catch /在调用EndAcceptSocket方法时可能引发异常 /套接字Listener被关闭,则设置为未启动侦听状态 IsStart = false; private void ReceiveCallback(IAsyncResult ar) MyFriend frd = (MyFriend)ar.AsyncState; int i = frd.socket.EndReceive(ar); if (i = 0) comboBoxClient.Invoke(Removefriend, frd); string da
14、ta = Encoding.UTF8.GetString(frd.Rcvbuffer, 0, i); data = string.Format(From0:1, frd.socket.RemoteEndPoint.ToString(), data); listBoxStatu.Invoke(AppendString, data); AsyncCallback callback = new AsyncCallback(ReceiveCallback); private void SendData(MyFriend frd, string data) byte msg = Encoding.UTF
15、8.GetBytes(data); AsyncCallback callback = new AsyncCallback(SendCallback); frd.socket.BeginSend(msg, 0, msg.Length, SocketFlags.None, callback, frd);To0: private void SendCallback(IAsyncResult ar) frd.socket.EndSend(ar); private void buttonSendMessage_Click(object sender, EventArgs e) if (textBoxMe
16、ssage.Text.Trim() = ) listBoxStatu.Items.Add(不能发送空字符串!); textBoxMessage.Focus(); if (comboBoxClient.SelectedIndex 0)请在列表中选择发送对象! int i = comboBoxClient.SelectedIndex; SendData(MyFriend)friendsi, textBoxMessage.Text.Trim(); private void buttonStop_Click(object sender, EventArgs e) if (!IsStart) liste
17、ner.Stop(); listBoxStatu.Invoke(AppendString, 已经结束了服务器的侦听! this.buttonStart.Enabled = true; private void buttonClear_Click(object sender, EventArgs e) this.listBoxStatu.Items.Clear(); public List getIP() listIP = new List(); string HostName = Dns.GetHostName(); /得到主机名 IPHostEntry IpEntry = Dns.GetHo
18、stEntry(HostName); for (int i = 0; i IpEntry.AddressList.Length; i+) /从IP地址列表中筛选出IPv4类型的IP地址 /AddressFamily.InterNetwork表示此IP为IPv4, /AddressFamily.InterNetworkV6表示此地址为IPv6类型 if (IpEntry.AddressListi.AddressFamily = AddressFamily.InterNetwork) listIP.Add(IpEntry.AddressListi.ToString(); return listIP
19、; catch (Exception ex) MessageBox.Show(获取本机IP出错: + ex.Message); listIP.Clear();客户端核心代码:package com.example.sockettest2;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import .Socket;import .UnknownHostException;import andr
20、oid.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.EditText;import android.widget.TextView;public class MainActivity extends Activity private TextView textR
21、eceive = null; private EditText textSend = null; private Button btnConnect = null; private Button btnSend = null; private static final String ServerIP = 10.0.2.2 private static final int ServerPort = 4567; private Socket socket = null; private String strMessage; private boolean isConnect = false; pr
22、ivate OutputStream outStream; private Handler myHandler = null; private ReceiveThread receiveThread = null; private boolean isReceive = false; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textReceive = (TextVi
23、ew)findViewById(R.id.textViewReceive); textSend = (EditText)findViewById(R.id.editTextSend); btnConnect = (Button)findViewById(R.id.buttonConnect); btnSend = (Button)findViewById(R.id.buttonSend); /连接按钮的监听器 btnConnect.setOnClickListener(new View.OnClickListener() Override public void onClick(View v)
24、 / TODO Auto-generated method stub if (!isConnect) new Thread(connectThread).start(); ); /发送按钮的监听器 btnSend.setOnClickListener(new View.OnClickListener() strMessage = textSend.getText().toString(); new Thread(sendThread).start(); myHandler = new Handler() public void handleMessage(Message msg) textRe
25、ceive.append(msg.obj).toString(); ; /连接到服务器的接口 Runnable connectThread = new Runnable() Override public void run() / TODO Auto-generated method stub try /初始化Scoket,连接到服务器 socket = new Socket(ServerIP, ServerPort); isConnect = true; /启动接收线程 isReceive = true; receiveThread = new ReceiveThread(socket); receiveThread.start(); System.out.println(-
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1