实例介绍
【实例简介】
【实例截图】

【核心代码】
服务端:
using System;
using System.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.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace 手机摄像头
{
public partial class MainForm : Form
{
/// <summary>
/// 服务器状态,如果为false表示服务器暂停,true表示服务器开启
/// </summary>
public bool ServerStatus = false;
/// <summary>
/// 服务器地址
/// </summary>
public string ServerAddress;
/// <summary>
/// 服务器端口
/// </summary>
public int ServerPort;
/// <summary>
/// 开启服务的线程
/// </summary>
private Thread processor;
/// <summary>
/// 用于TCP监听
/// </summary>
private TcpListener tcpListener;
/// <summary>
/// 与客户端连接的套接字接口
/// </summary>
private Socket clientSocket;
/// <summary>
/// 用于处理客户事件的线程
/// </summary>
private Thread clientThread;
/// <summary>
/// 手机客户端所有客户端的套接字接口
/// </summary>
private Hashtable PhoneClientSockets = new Hashtable();
/// <summary>
/// 手机用户类数组
/// </summary>
public ArrayList PhoneUsersArray = new ArrayList();
/// <summary>
/// 手机用户名数组
/// </summary>
public ArrayList PhoneUserNamesArray = new ArrayList();
/// <summary>
/// 图像数据流
/// </summary>
private ArrayList StreamArray;
public MainForm()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
}
private void phoneslistView_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (phoneslistView.SelectedItems != null &&
phoneslistView.SelectedItems.Count > 0)
{
ListViewItem tempItem = phoneslistView.SelectedItems[0];
string tempUserName = tempItem.SubItems[1].Text;
int tempIndex = GetPhoneUserIndex(tempUserName);
if (tempIndex >= 0)
{
UserClass tempUser = (UserClass)(PhoneUsersArray[tempIndex]);
if (tempUser != null)
{
PhoneVideoForm form = new PhoneVideoForm(tempUser);
this.AddOwnedForm(form);
form.Show();
}
}
}
}
#region 开启服务
/// <summary>
/// 开启服务
/// </summary>
public void StartServer()
{
try
{
if (this.ServerStatus)//服务器已经开启
{
MessageBox.Show("服务已经开启!");
}
else
{
processor = new Thread(new ThreadStart(StartListening));//建立监听服务器地址及端口的线程
processor.Start();
processor.IsBackground = true;
StreamArray = new ArrayList();
PhoneUserNamesArray = new ArrayList();
}
停止服务器button.Enabled = true;
开启服务器button.Enabled = false;
this.ServerStatus = true;
}
catch (Exception except)
{
MessageBox.Show(except.Message,
"提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
#endregion
#region 停止服务
/// <summary>
/// 停止服务
/// </summary>
public void StopServer()
{
try
{
if (this.ServerStatus)
{
tcpListener.Stop();
Thread.Sleep(1000);
processor.Abort();
}
else
MessageBox.Show("服务已经停止!");
停止服务器button.Enabled = false;
开启服务器button.Enabled = true;
this.ServerStatus = false;
}
catch (Exception except)
{
MessageBox.Show(except.Message,
"提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
#endregion
/// <summary>
/// 开始监听服务器地址和端口
/// </summary>
private void StartListening()
{
try
{
IPAddress ipAddress = IPAddress.Parse(ServerAddress);
tcpListener = new TcpListener(ipAddress, ServerPort);//建立指定服务器地址和端口的TCP监听
tcpListener.Start();//开始TCP监听
while (true)
{
Thread.Sleep(50);
try
{
Socket tempSocket = tcpListener.AcceptSocket();//接受挂起的连接请求
clientSocket = tempSocket;
clientThread = new Thread(new ThreadStart(ProcessClient));//建立处理客户端传递信息的事件线程
//线程于后台运行
clientThread.IsBackground = true;
clientThread.Start();
}
catch (Exception e)
{
}
}
}
catch
{
this.ServerStatus = false;
processor.Abort();
}
}
#region 处理客户端传递数据及处理事情
/// <summary>
/// 处理客户端传递数据及处理事情
/// </summary>
private void ProcessClient()
{
Socket client = clientSocket;
bool keepalive = true;
while (keepalive)
{
Thread.Sleep(50);
Byte[] buffer = null;
bool tag = false;
try
{
buffer = new Byte[1024];//client.Available
int count = client.Receive(buffer, SocketFlags.None);//接收客户端套接字数据
if (count > 0)//接收到数据
tag = true;
}
catch (Exception e)
{
keepalive = false;
if (client.Connected)
client.Disconnect(true);
client.Close();
}
if (!tag)
{
if (client.Connected)
client.Disconnect(true);
client.Close();
keepalive = false;
}
string clientCommand = "";
try
{
clientCommand = System.Text.Encoding.UTF8.GetString(buffer);//转换接收的数据,数据来源于客户端发送的消息
if (clientCommand.Contains("%7C"))//从Android客户端传递部分数据
clientCommand = clientCommand.Replace("%7C", "|");//替换UTF中字符%7C为|
}
catch
{
}
//分析客户端传递的命令来判断各种操作
string[] messages = clientCommand.Split('|');
if (messages != null && messages.Length > 0)
{
string tempStr = messages[0];//第一个字符串为命令
if (tempStr == "PHONECONNECT")//手机连接服务器
{
try
{
string tempClientName = messages[1].Trim();
PhoneClientSockets.Remove(messages[1]);//删除之前与该用户的连接
PhoneClientSockets.Add(messages[1], client);//建立与该客户端的Socket连接
UserClass tempUser = new UserClass();
tempUser.UserName = tempClientName;
tempUser.LoginTime = DateTime.Now;
Socket tempSocket = (Socket)PhoneClientSockets[tempClientName];
tempUser.IPAddress = tempSocket.RemoteEndPoint.ToString();
int tempIndex = PhoneUserNamesArray.IndexOf(tempClientName);
if (tempIndex >= 0)
{
PhoneUserNamesArray[tempIndex] = tempClientName;
PhoneUsersArray[tempIndex] = tempUser;
MemoryStream stream2 = (MemoryStream)StreamArray[tempIndex];
if (stream2 != null)
{
stream2.Close();
stream2.Dispose();
}
}
else//新增加
{
PhoneUserNamesArray.Add(tempClientName);
PhoneUsersArray.Add(tempUser);
StreamArray.Add(null);
}
RefreshPhoneUsers();
}
catch (Exception except)
{
}
}
else if (tempStr == "PHONEDISCONNECT")//某个客户端退出了
{
try
{
string tempClientName = messages[1];
RemovePhoneUser(tempClientName);
int tempPhoneIndex = PhoneUserNamesArray.IndexOf(tempClientName);
if (tempPhoneIndex >= 0)
{
PhoneUserNamesArray.RemoveAt(tempPhoneIndex);
MemoryStream memStream = (MemoryStream)StreamArray[tempPhoneIndex];
if (memStream != null)
{
memStream.Close();
memStream.Dispose();
}
StreamArray.RemoveAt(tempPhoneIndex);
}
Socket tempSocket = (Socket)PhoneClientSockets[tempClientName];//第1个为客户端的ID,找到该套接字
if (tempSocket != null)
{
tempSocket.Close();
PhoneClientSockets.Remove(tempClientName);
}
keepalive = false;
}
catch (Exception except)
{
}
RefreshPhoneUsers();
}
else if (tempStr == "PHONEVIDEO")//接收手机数据流
{
try
{
string tempClientName = messages[1];
string tempForeStr = messages[0] "%7C" messages[1] "%7C";
int startCount = System.Text.Encoding.UTF8.GetByteCount(tempForeStr);
try
{
MemoryStream stream = new MemoryStream();
if (stream.CanWrite)
{
stream.Write(buffer, startCount, buffer.Length - startCount);
int len = -1;
while ((len = client.Receive(buffer)) > 0)
{
stream.Write(buffer, 0, len);
}
}
stream.Flush();
int tempPhoneIndex = PhoneUserNamesArray.IndexOf(tempClientName);
if (tempPhoneIndex >= 0)
{
MemoryStream stream2 = (MemoryStream)StreamArray[tempPhoneIndex];
if (stream2 != null)
{
stream2.Close();
stream2.Dispose();
}
StreamArray[tempPhoneIndex] = stream;
PhoneVideoForm form = GetPhoneVideoForm(tempClientName);
if (form != null)
form.DataStream = stream;
}
}
catch
{
}
}
catch (Exception except)
{
}
}
}
else//客户端发送的命令或字符串为空,结束连接
{
try
{
client.Close();
keepalive = false;
}
catch
{
keepalive = false;
}
}
}
}
#endregion
#region 刷新手机用户列表
/// <summary>
/// 刷新手机用户列表
/// </summary>
public void RefreshPhoneUsers()
{
phoneslistView.Items.Clear();
if (PhoneUsersArray != null && PhoneUsersArray.Count > 0
&& PhoneClientSockets != null && PhoneClientSockets.Count > 0)
{
int i, count = PhoneUsersArray.Count;
UserClass tempUser;
ListViewItem tempItem;
ListViewItem.ListViewSubItem tempSubItem;
Color tempColor;
Socket tempSocket;
for (i = 0; i < count; i )
{
tempUser = (UserClass)PhoneUsersArray[i];
tempSocket = (Socket)PhoneClientSockets[tempUser.UserName];
tempItem = phoneslistView.Items.Add((i 1).ToString());
if (tempUser.Enable)
tempColor = Color.Blue;
else
tempColor = Color.Red;
tempItem.ForeColor = tempColor;
tempSubItem = tempItem.SubItems.Add(tempUser.UserName);
tempSubItem.ForeColor = tempColor;
tempSubItem = tempItem.SubItems.Add(tempUser.IPAddress);
tempSubItem.ForeColor = tempColor;
tempSubItem = tempItem.SubItems.Add(tempUser.LoginTime.ToString());
tempSubItem.ForeColor = tempColor;
}
}
}
#endregion
#region 获取手机视频窗体
/// <summary>
/// 获取手机视频窗体
/// </summary>
/// <param name="username"></param>
/// <returns></returns>
public PhoneVideoForm GetPhoneVideoForm(string username)
{
PhoneVideoForm form = null;
foreach (Form tempForm in this.OwnedForms)
{
if (tempForm is PhoneVideoForm)
{
PhoneVideoForm tempForm2 = tempForm as PhoneVideoForm;
if (tempForm2.UserName == username)
{
form = tempForm2;
break;
}
}
}
return form;
}
#endregion
#region 删除手机用户
/// <summary>
/// 从当前用户列表中删除指定用户
/// </summary>
/// <param name="userName"></param>
public void RemovePhoneUser(string userName)
{
if (PhoneUsersArray != null && PhoneUsersArray.Count > 0)
{
int i = 0;
foreach (UserClass tempUser in PhoneUsersArray)
if (tempUser.UserName == userName)
{
PhoneUsersArray.RemoveAt(i);
break;
}
else
i ;
}
}
#endregion
#region 寻找用户所在序号
/// <summary>
/// 寻找用户所在序号
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public int GetPhoneUserIndex(string userName)
{
int result = -1;
if (PhoneUserNamesArray != null && PhoneUserNamesArray.Count > 0)
{
int i = 0;
foreach (string tempName in PhoneUserNamesArray)
if (tempName == userName)
{
result = i;
break;
}
else
i ;
}
return result;
}
#endregion
private void 开启服务器button_Click(object sender, EventArgs e)
{
ServerAddress = iptextBox.Text;
int tempPort = 8888;
if (int.TryParse(porttextBox.Text, out tempPort))
{
ServerPort = tempPort;
StartServer();
}
else
{
MessageBox.Show("端口设置不正确!");
}
}
private void 停止服务器button_Click(object sender, EventArgs e)
{
StopServer();
}
}
}
客户端:
package com.xzy;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
public class SocketCameraActivity extends Activity implements SurfaceHolder.Callback,
Camera.PreviewCallback{
private SurfaceView mSurfaceview = null; // SurfaceView对象:(视图组件)视频显示
private SurfaceHolder mSurfaceHolder = null; // SurfaceHolder对象:(抽象接口)SurfaceView支持类
private Camera mCamera = null; // Camera对象,相机预览
/**服务器地址*/
private String pUsername="XZY";
/**服务器地址*/
private String serverUrl="192.168.1.100";
/**服务器端口*/
private int serverPort=8888;
/**视频刷新间隔*/
private int VideoPreRate=1;
/**当前视频序号*/
private int tempPreRate=0;
/**视频质量*/
private int VideoQuality=85;
/**发送视频宽度比例*/
private float VideoWidthRatio=1;
/**发送视频高度比例*/
private float VideoHeightRatio=1;
/**发送视频宽度*/
private int VideoWidth=320;
/**发送视频高度*/
private int VideoHeight=240;
/**视频格式索引*/
private int VideoFormatIndex=0;
/**是否发送视频*/
private boolean startSendVideo=false;
/**是否连接主机*/
private boolean connectedServer=false;
private Button myBtn01, myBtn02;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//禁止屏幕休眠
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mSurfaceview = (SurfaceView) findViewById(R.id.camera_preview);
myBtn01=(Button)findViewById(R.id.button1);
myBtn02=(Button)findViewById(R.id.button2);
//开始连接主机按钮
myBtn01.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
//Common.SetGPSConnected(LoginActivity.this, false);
if(connectedServer){//停止连接主机,同时断开传输
startSendVideo=false;
connectedServer=false;
myBtn02.setEnabled(false);
myBtn01.setText("开始连接");
myBtn02.setText("开始传输");
//断开连接
Thread th = new MySendCommondThread("PHONEDISCONNECT|" pUsername "|");
th.start();
}
else//连接主机
{
//启用线程发送命令PHONECONNECT
Thread th = new MySendCommondThread("PHONECONNECT|" pUsername "|");
th.start();
connectedServer=true;
myBtn02.setEnabled(true);
myBtn01.setText("停止连接");
}
}});
myBtn02.setEnabled(false);
myBtn02.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
if(startSendVideo)//停止传输视频
{
startSendVideo=false;
myBtn02.setText("开始传输");
}
else{ // 开始传输视频
startSendVideo=true;
myBtn02.setText("停止传输");
}
}});
}
@Override
public void onStart()//重新启动的时候
{
mSurfaceHolder = mSurfaceview.getHolder(); // 绑定SurfaceView,取得SurfaceHolder对象
mSurfaceHolder.addCallback(this); // SurfaceHolder加入回调接口
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 设置显示器类型,setType必须设置
//读取配置文件
SharedPreferences preParas = PreferenceManager.getDefaultSharedPreferences(SocketCameraActivity.this);
pUsername=preParas.getString("Username", "XZY");
serverUrl=preParas.getString("ServerUrl", "192.168.0.100");
String tempStr=preParas.getString("ServerPort", "8888");
serverPort=Integer.parseInt(tempStr);
tempStr=preParas.getString("VideoPreRate", "1");
VideoPreRate=Integer.parseInt(tempStr);
tempStr=preParas.getString("VideoQuality", "85");
VideoQuality=Integer.parseInt(tempStr);
tempStr=preParas.getString("VideoWidthRatio", "100");
VideoWidthRatio=Integer.parseInt(tempStr);
tempStr=preParas.getString("VideoHeightRatio", "100");
VideoHeightRatio=Integer.parseInt(tempStr);
VideoWidthRatio=VideoWidthRatio/100f;
VideoHeightRatio=VideoHeightRatio/100f;
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
InitCamera();
}
/**初始化摄像头*/
private void InitCamera(){
try{
mCamera = Camera.open();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onPause() {
super.onPause();
try{
if (mCamera != null) {
mCamera.setPreviewCallback(null); // !!这个必须在前,不然退出出错
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
if (mCamera == null) {
return;
}
mCamera.stopPreview();
mCamera.setPreviewCallback(this);
mCamera.setDisplayOrientation(90); //设置横行录制
//获取摄像头参数
Camera.Parameters parameters = mCamera.getParameters();
Size size = parameters.getPreviewSize();
VideoWidth=size.width;
VideoHeight=size.height;
VideoFormatIndex=parameters.getPreviewFormat();
mCamera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (null != mCamera) {
mCamera.setPreviewCallback(null); // !!这个必须在前,不然退出出错
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
//如果没有指令传输视频,就先不传
if(!startSendVideo)
return;
if(tempPreRate<VideoPreRate){
tempPreRate ;
return;
}
tempPreRate=0;
try {
if(data!=null)
{
YuvImage image = new YuvImage(data,VideoFormatIndex, VideoWidth, VideoHeight,null);
if(image!=null)
{
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
//在此设置图片的尺寸和质量
image.compressToJpeg(new Rect(0, 0, (int)(VideoWidthRatio*VideoWidth),
(int)(VideoHeightRatio*VideoHeight)), VideoQuality, outstream);
outstream.flush();
//启用线程将图像数据发送出去
Thread th = new MySendFileThread(outstream,pUsername,serverUrl,serverPort);
th.start();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**创建菜单*/
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(0,0,0,"系统设置");
menu.add(0,1,1,"关于程序");
menu.add(0,2,2,"退出程序");
return super.onCreateOptionsMenu(menu);
}
/**菜单选中时发生的相应事件*/
public boolean onOptionsItemSelected(MenuItem item)
{
super.onOptionsItemSelected(item);//获取菜单
switch(item.getItemId())//菜单序号
{
case 0:
//系统设置
{
Intent intent=new Intent(this,SettingActivity.class);
startActivity(intent);
}
break;
case 1://关于程序
{
new AlertDialog.Builder(this)
.setTitle("关于本程序")
.setMessage("本程序由武汉大学水利水电学院肖泽云设计、编写。\nEmail:xwebsite@163.com")
.setPositiveButton
(
"我知道了",
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
}
}
)
.show();
}
break;
case 2://退出程序
{
//杀掉线程强制退出
android.os.Process.killProcess(android.os.Process.myPid());
}
break;
}
return true;
}
/**发送命令线程*/
class MySendCommondThread extends Thread{
private String commond;
public MySendCommondThread(String commond){
this.commond=commond;
}
public void run(){
//实例化Socket
try {
Socket socket=new Socket(serverUrl,serverPort);
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(commond);
out.flush();
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
}
/**发送文件线程*/
class MySendFileThread extends Thread{
private String username;
private String ipname;
private int port;
private byte byteBuffer[] = new byte[1024];
private OutputStream outsocket;
private ByteArrayOutputStream myoutputstream;
public MySendFileThread(ByteArrayOutputStream myoutputstream,String username,String ipname,int port){
this.myoutputstream = myoutputstream;
this.username=username;
this.ipname = ipname;
this.port=port;
try {
myoutputstream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try{
//将图像数据通过Socket发送出去
Socket tempSocket = new Socket(ipname, port);
outsocket = tempSocket.getOutputStream();
//写入头部数据信息
String msg=java.net.URLEncoder.encode("PHONEVIDEO|" username "|","utf-8");
byte[] buffer= msg.getBytes();
outsocket.write(buffer);
ByteArrayInputStream inputstream = new ByteArrayInputStream(myoutputstream.toByteArray());
int amount;
while ((amount = inputstream.read(byteBuffer)) != -1) {
outsocket.write(byteBuffer, 0, amount);
}
myoutputstream.flush();
myoutputstream.close();
tempSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论