手机tcp怎么linux开启tcp端口

2016年1月 总版技术专家分月排行榜第二2015年11月 总版技术专家分月排行榜第二2015年10月 总版技术专家分月排行榜第二
优秀小版主
2015年9月 总版技术专家分月排行榜第二
2015年8月 总版技术专家分月排行榜第三
2015年3月 .NET技术大版内专家分月排行榜第三2015年2月 .NET技术大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。安全市场联盟开放平台
如果你是应用开发者欢迎提交软件到360
下载的人还喜欢
本类热门应用
TCP连接是TCP连接测试工具。它易于使用,可以用于Android手机间、或者与其它设备的TCP通信以及TCP连接测试。&
TCP连接的特点:&
支持TCP客户端和服务器模式。&
键盘视图,可以自定义按键。&
支持使用GPRS连接。&
可以用来与其他Android手机或者设备TCP通信。&
可以设置为ASCII或HEX显示模式。&
可设置终端或聊天视图。&
可设置传输编码。
【更新内容】1. UI部分优化
2. 修复先前版本的不稳定
3. 支持新版本检测
保持登录状态
您的赞美就是给作者最大的回报,觉得好就表扬TA一下吧。
还可以输入200字
该应用暂时还没有评论,沙发空缺中。
应用评分:7.8分
大家的选择就是正确的选择,你值得拥有
请先下载此应用,才可对其评分。
我来评分:
通过360手机卫士检测
安全无毒,可放心下载。
- 有内置广告
- 有插屏广告
需要调用以下重要权限
-&访问网络-&读取电话状态-&获取网络状态-&获取WiFi状态
Copyright&2005- All Rights Reserved 360安全中心18295人阅读
Android网络开发(3)
本文背景:局域网内手机与手机利用wifi建立tcp连接,通过socket互传照片。即一个手机当作服务器,另一个手机是客户端,客户端可以看到服务器指定文件夹内的图片缩略图,并选择下载到本机。另外,客户端会显示本地某个文件夹内的图片缩略图,并选择上传到服务器。总而言之本例中图片的发送和接收都是双向的。除发送图片外,还含有字符串(图片的名字)、文件夹内图片的个数(刷新适配器)的发送。 众所周知,android常用的网络开发无外乎http和socket,其中http是应用层的协议,tcp是传输层。所以,http也是用socket封装的,用起来更方便。由于是封装过的,它提供了更强大的功能。socket又分为TCP和UDP,局域网内TCP速度就很快了,鉴于局域网内传送东西不需要考虑流量,所以此种场合多用socket。首先看下本例的运行效果: 下面是客户端初始界面: 点击下载后进入下载界面,服务器就开始给客户端传缩略图和图片的名字了,如下: 选择需要下载的图片: 点击确定按钮后,服务器就开始给客户端传大图了,就是原始图片,传输完毕后,弹出提示框: 点击上面的确定后,就自动结束当前activity,返回到初始界面,就不附图了。 下面是客户端的上传界面,将图片上传到服务器上,这个没啥难的,就是本地图片生成缩略图填充到listview上,不涉及到网络部分。其传输,跟服务器往客户端传东西是一样的。: 最后来看下服务器,由于服务器没任何UI上的要求,所以就是些简单的log打印: 本以为很简单的一个功能,但网上大多数是手机是客户端,PC是服务端。虽然都是流传输,但服务器在PC和手机上解析成图片还是不大一样的,中间走了很多弯路才搞定,另外,就是网上大多是简单的收发,本例中既要传输图片个数、图片名字等,客户端牵涉到切换到activity,要多个socket链接,还是有些麻烦的。下面把开发中遇到的问题、开发要点和步骤记录下来。1、权限问题 这里包括WIFI权限,Internet权限和文件读写权限。我第一次的时候权限没添加完,来来回回折腾了好几次。服务器和客户端的权限是一样的.
&uses-permission android:name=&android.permission.ACCESS_WIFI_STATE& /&
&uses-permission android:name=&android.permission.CHANGE_WIFI_STATE& /&
&uses-permission android:name=&android.permission.ACCESS_NETWORK_STATE& /&
&uses-permission android:name=&android.permission.INTERNET& /&
&uses-permission android:name=&android.permission.MOUNT_UNMOUNT_FILESYSTEMS& /&
&uses-permission android:name=&android.permission.WRITE_EXTERNAL_STORAGE& /&2、服务器再开启服务前,首先要判断WIFI是否连接,如果没有WIFI连接应该弹出个提示框。如果有WIFI连接上了,则进一步提取出IP地址。我将其封装到NetworkUtil类里弄成静态方法,如下:package org.yanzi.
import android.content.C
import android.net.ConnectivityM
import android.net.NetworkI
import android.net.wifi.WifiI
import android.net.wifi.WifiM
public class NetworkUtil {
*判断wifi是否连接
* @param context
public static boolean isWiFiConnected(Context context){
ConnectivityManager connectManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if(networkInfo.isConnected()){
* 得到wifi连接的IP地址
* @param context
public static String getWifiIP(Context context){
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddr = wifiInfo.getIpAddress();
String ipStr =
int2string(ipAddr);
return ipS
* 输入int 得到String类型的ip地址
* @param i
private static String int2string(int i){
return (i & 0xFF)+ &.& + ((i && 8 ) & 0xFF) + &.& + ((i && 16 ) & 0xFF) +&.&+((i && 24 ) & 0xFF );
在wifi地址这块,当时还参考了网上一个,但是转出来的string类型的IP地址是错误的,上面贴的代码是正确的。如果wifi没有连接,则弹出提示框报错: public void showAlterDialog(){
Dialog alterDialog = new AlertDialog.Builder(this).
setTitle(&警告&).
setMessage(&当前WiFi没有正常连接,请连接后再操作.&).
setIcon(android.R.drawable.ic_dialog_alert).
setPositiveButton(&确定&, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
alterDialog.show();
}3、服务器点击开启服务后,如果WIFI连接好了。service没有运行就要开启Service了。当前Activity名字为ServerActivity,服务是TCPService。if(!isServiceRun){
startService(new Intent(ServerActivity.this,TCPService.class));
noticeTextView.append(&\n& + &服务已开启,& + &正在服务...&+&\n&);
manageButton.setText(&销毁共享服务&);
isServiceRun =
stopService(new Intent(ServerActivity.this, TCPService.class));
noticeTextView.append(&\n& + &服务已销毁&+&\n&);
isServiceRun =
manageButton.setText(&开启共享服务&);
}4、服务器端因为用了service,所以牵涉到Activity和Service的通信问题,最常见的莫过于用广播了。在ServerActivity里定义一个继承BroadcastReceiver的类。 /**
* @author Administrator
*Activity接收Service消息,更新UI
public class MsgReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String s = intent.getStringExtra(&INFO&);
noticeTextView.append(s);
}在onCreate()里实例化并注册:msgReceiver = new MsgReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(&org.yanzi.shareserver.receiver&);
registerReceiver(msgReceiver, intentFilter);其中的addAction是为了区别哪个广播。这个标签和Service里保持同步。如果是有多个Service的话,Activity利用它来区分是哪个Service发来的广播。然后再Service里利用下面代码给Activity发广播:private Intent mIntent = new Intent(&org.yanzi.shareserver.receiver&); /**
* 通知Activity更新UI
* @param s
* @param len
public void sendBroadcastString(String s, int len){
mIntent.putExtra(&INFO&, s +&长度
= &+ len+ &\n&);
sendBroadcast(mIntent);
mIntent.removeExtra(&INFO&);
}mIntent发送完消息后就remove一下。5、接着就轮到Service上场了。想对于一般的Socket DEMO服务器功能都比较单一,本例的Service任务和逻辑如下: a、首先有个全局的socket,负责监听客户端的请求,是 下载 还是上传; b、如果监听到是下载,就把这个socket关闭。然后再开个socket和客户端连接,此时对应的客户端页面也进行了切换,客户端也开了一个socket负责接收图片的。在传输图片时一定要先传递图片的个数,否则的话客户端的listview没法实例化,不知道view有多少个。【备注:Socket的对等性】 Socket的对等性一定要时刻清晰,socket就像一条线的两个端,连接服务器和客户端。服务器的socket对等于客户端的socket,是一一对应的。其实用对应还不大准确,就如同手心和手背一样,一体两面。因此服务器和客户端,两端的socket如果连接好了,任何一端关闭socket都会造成对方的socket关闭。不仅如此,socket、输入流、输出流,三者有任何一个关闭都会造成整个socket连接的关闭。但输出流的flush()函数不会造成这个问题,在发送东西时flush也是必须的。因此,大量网上给出的socket示例,说发送完毕后都要把输出流close()掉其实是不对的。如果有多个图片,一定要等图片发送完毕后,再去close。6、服务器的Service里可以弄个死循环一直监听,也可以弄个线程一直监听。这里是弄的线程ServiceThread,如果要考虑多客户端,这块要弄成线程池,即来一个客户端连接上,就专门开个线程来处理。在Service的onCreate函数里new一个ServertSocket,将监听的线程实例化: /**
* 初始化ServerSocket,buffer分配内存
public void initTCPService(){
mServerSocket = new ServerSocket(PORT);
Log.i(tag, &Service启动监听...&);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if(mServiceThread == null){
mServiceThread = new ServiceThread();
}此后mServerSocket就会一直监听PORT端口。下面是我的ServiceThread的完整实现: class ServiceThread extends Thread{
public void run() {
// TODO Auto-generated method stub
while(allowRun){
client = mServerSocket.accept();
Log.i(tag, &Service监听到消息...&);
InputStream inputStream = client.getInputStream();
int temp = 0;
while((temp = inputStream.read(mByteBuffer)) != -1){
if(temp & 10){
String s = new String(mByteBuffer, 0, temp);
inputStream.close();
client.close();
if(s.trim().equals(new String(&DOWNLOAD&))){
sendBroadcastString(&客户端下载开始:& + s, temp);
sendThumnail(SRC_PAH);
else if(s.trim().equals(new String(&UPLOAD&))){
sendBroadcastString(&客户端上传开始:& + s, temp);
getUploadImages();
String s = new String(mByteBuffer, 0, temp);
Log.i(tag, &temp = & + temp+& = & + s);
inputStream.close();
if(client.isConnected()){
client.close();
sendBroadcastString(&服务器:收到客户端的下载列表 = & + s,temp);
sendImage(s.trim());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} 这个Thread一旦运行就会进入死循环,如果服务端监听到有客户端连接,client = mServerSocket.accept(); client的类型是Socket。之后程序会阻塞在InputStream inputStream = client.getInputStream();这一句,而不是上面的accept()这里。 简单介绍下InputStream和OutputStream,当socket是接收方时,就用Socket.getInputStream(),得到的是输入流。如果是socket想发送东西,就用Socket.getOutputStream。无论是输入流还是输出流,都是为了和基本数据类型进行转换。何为基础数据类型?比如byte[]这些。其实InputStream是利用read函数,将输入流的东西read到基础数据类型里。OutputStream是利用write函数,将基本数据类型的东西write到流里面。 上面的代码中,首先判断客户端发来的是字符串有多长,如果小于10,则认为他是命令级的,即要么是上传或下载。根据上传或下载再跳到具体的函数里开一个新的socket去发送和接收图片。如果string的长度大于10,那就认为是客户端勾选的下载列表的名字。其实这么搞不大精确,可以客户端和服务端约定好,流的第一个字节写进入一个int,用来区分判断是下载和上传,及其他功能。7、手机与手机TCP Socket发送字符串: 最简单的就是writeUTF然后接收方readUTF就ok来了。我这里弄的还是有点复杂了,见客户端里的sendMsgToServer函数。8、手机与手机TCP Socket发送图片,这里是以服务端上的发送图片和接收图片来示例的:发送图片个数:Socket socket =
Bitmap bitmap =
socket = mServerSocket.accept();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
//第一次发送文件夹内有多少个图片
int num = listFile.
DataOutputStream dos1 = new DataOutputStream(socket.getOutputStream());
dos1.writeInt(num);
dos1.flush();
Log.i(tag, &服务端:文件夹下图片数 = & + num);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} 先往流里写入有多少个图片,将来客户端readInt读出来传给适配器。下面是发送图片:FileInputStream fileStream = new FileInputStream(listFile[i]);
bitmap = BitmapFactory.decodeStream(fileStream);
Bitmap thumBitmap = ThumbnailUtils.extractThumbnail(bitmap, THUM_WIDTH, THUM_HEIGHT);
ImageUtil.saveJpeg(thumBitmap);
//发送给客户端
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pressFormat.JPEG, 85, baos);
Log.i(tag, &baos.size() & + baos.size());
dos.writeInt(baos.size());
byte[] bytes = baos.toByteArray();
dos.write(bytes);
dos.writeUTF(name);//写进去名字
dos.flush(); 在已有Bitmap的情况,Bitmap---compress到ByteArrayOutPutStream baos-----baos转到byte[] bytes里,然后将基础数据byte[] bytes write到dos里取,dos的类型如下:DataOutputStream dos = new DataOutputStream(socket.getOutputStream());接收图片,还是以服务器为例,我就把接收客户端传来的照片函数getUploadImages()完整贴出来:public void getUploadImages(){
Socket socket =
int numNeedDownload = 0;
socket = mServerSocket.accept();
DataInputStream is = new DataInputStream(socket.getInputStream());
numNeedDownload = is.readInt(); //获得需要下载的个数
sendBroadcastString(&服务器:客户端将要上传文件个数 = & +numNeedDownload, 000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
for(int i=0; i&numNeedD i++){
DataInputStream is = new DataInputStream(socket.getInputStream());
int size = is.readInt(); //得到byte的长度
byte[] buffer = new byte[size];
int len = 0;
while(len & size){
len += is.read(buffer, len, size-len);
Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
if(bitmap == null){
Log.i(tag, &服务器:bitmap为空&);
String name = is.readUTF();
ImageUtil.saveJpeg(bitmap, name);
sendBroadcastString(&服务器:&+name+&接收成功&, 000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//接收完毕后,关闭socket
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} 首先获得需要下载的个数,然后进入一个循环。将得到的输入流读到byte里,这里通过
int size = is.readInt(); //得到byte的长度
byte[] buffer = new byte[size];
int len = 0;
while(len & size){
len += is.read(buffer, len, size-len);
}先获得输入流里存的照片的byte长度,然后进入while循环,读到buffer里。之后就是BitmapFactory解析了。再从流里读出来图片的名字。客户端部分:1、客户端跟服务器端差不多,唯一不同的是服务器是ServertSocket负责监听,监听到连接后调用accept()函数得到socket。而客户端是直接new一个socket,连接服务器。需要注意客户端的点击下载和上传的执行要写在单独的线程里,自从android4.0后,关于网络的操作都不能放在主线程里。下面的代码是客户端向服务器发送选择的下载列表名字: /**
* @author Administrator
*发送给服务器,需要下载的图片的名字
class SendDownName implements Runnable{
public void run() {
// TODO Auto-generated method stub
String sendName = getNeedDownNames();
Socket socket = new Socket(Ip, Port);
sendMsgToServer(socket, sendName);
socket.close();
mainHanlder.sendEmptyMessage(START_DOWNLOAD_ASYNCTASK);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
public void sendMsgToServer(Socket socket, String s){
OutputStreamWriter outputStrWriter = new OutputStreamWriter(socket.getOutputStream());
BufferedWriter buffWriter = new BufferedWriter(outputStrWriter);
PrintWriter printWriter = new PrintWriter(buffWriter);
printWriter.println(s);
printWriter.flush();
printWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} 当发送完毕后,给mainandler传一个消息,开一个异步线程类来接收图片。在下载缩略图过程中,每次接受到一个图片都应该通知listview的适配器更新一下,mainHanlder.sendEmptyMessage(UPDATE_LIST_ADAPTER);也是通过mainHandler来做的。 case UPDATE_LIST_ADAPTER:
listViewAdapter.notifyDataSetChanged();
2、客户端里用了AsyncTask,博主关于它的用法讲的十分透彻,参见: & 补充一点,在AsyncTask的onPreExecute() 、onPostExecute()都只能做主线程UI的事情,而不能操作网络这些主线程不允许做的事情。&AsyncTask&Void, Integer, Void&的第一个参数输入、第二个参数是中间值、第三个参数是输出。本例为了能接收到一个图片,就更新下progressbar,需要以下语句:在doInBackground()里 publishProgress(mCnt); 然后是下面的:
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
Log.i(tag, &进度条 = & + values[0]);
progressBar.setProgress(values[0]);
}本例遗留的问题: 现在是客户端接收到一个图片然后进度条走一下,但是我们用手机蓝牙传照片时,是一个图片在传输过程中就能显示进度的变化。这就需要在传输时,分好几份来传,然后合并。等完善了进度条的UI再贡献源码下载。------------------------本文系原创,转载请注明作者yanzi1225627&欢迎Android爱好者加群,群号: 备注: yanzi
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4269451次
积分:34190
积分:34190
排名:第112名
原创:367篇
转载:12篇
评论:2851条
文章:23篇
阅读:483903
(1)(3)(1)(3)(5)(5)(5)(8)(4)(3)(3)(7)(10)(4)(2)(3)(1)(3)(7)(2)(1)(4)(1)(3)(17)(14)(7)(8)(7)(6)(3)(7)(7)(3)(3)(7)(5)(6)(11)(24)(6)(11)(10)(13)(11)(34)(39)(2)(23)(6)}

我要回帖

更多关于 怎么开启tcp端口 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信