`
oham_一1一
  • 浏览: 49900 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java socket 入门 示例

阅读更多

面向连接传输协议(TCP)

两台电脑在传输数据前,会先建立一个专属的连接,就如打电话一般,双方通话时,会占有一条专属的通讯连接,当有一方挂机后,此连接就会消失。面向连接的协议特点:

  1. 确认回应:设甲乙两台电脑,当甲传数据到乙时,会等乙送回确认后才会再去传下一笔数据。当一段时间没有收到乙的确认回复,甲会试着再传一次,如果传送多次都没有回应,就表示连接可能断了。
  2. 分组序号:面向连接协议在传送数据的时候会把数据分割成固定大小的分组(packet),然后在每个分组上加上序号。序号用来检查哪些分组收到,哪些封包重复等。
  3. 流量控制

TCP是属于可靠性传输。

 

非面向连接传输协议(UDP)

与面向连接协议相比较,使用非连接协议传输数据的电脑间并不会建立一条专属的连接,这样的连接不可靠,分组可能丢失,可能收到重复的分组,也可能出现后面的分组比前面的分组先收到的情形。UDP协议一般用于短距离的传输,或者大量传输且容许些许错误的场合,如视频会议等,或者multicasting或则broadcasting。

 

连接端口

一台电脑可能同时运行着多个Server,那么此时还需要一个端口来明确客户端到底想连此台电脑的哪个Server。就如电话的分机号码,先拨通总机,然后总机根据提供的分机号码转到该分机。

 

Socket

Socket是程序与网络间的一种接口, 通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络,请求大部分的网络应用都是点对点的(point-to-point),所谓点就是服务端和客户端所执行的程序。Socket是用来接收或传送分组的一个端点。

 

Java中基本的 服务器——客户端 模型

服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。

 

客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。

 

示例代码:

 

 服务器端:

 

public class TCPEchoServer {

	public static final int PORT = 7777;
	public static final String ADDR = "127.0.0.1";
	
	protected void handleReq(Socket clnt) throws IOException
	{
		System.out.println("Client connected from: " + clnt.getInetAddress());
		
		System.out.println(clnt.isConnected()+ "~~~~" + clnt.isClosed());
		
		BufferedInputStream dataIn = new BufferedInputStream(clnt.getInputStream());
		
		byte[] b = new byte[64];
		
		int len = dataIn.read(b);
		
		String sendBack = new String(b, 0, len);
		sendBack = sendBack.toUpperCase();
		
		OutputStream dataOut = clnt.getOutputStream();
		
		dataOut.write(sendBack.getBytes());
		
		dataIn.close();
		
		dataOut.close();
		System.out.println(clnt.isConnected()+ "~~~~" + clnt.isClosed());
	}
	
	public void start()
	{
		try 
		{ 
			ServerSocket srv = new ServerSocket( PORT, 0, InetAddress.getByName(ADDR) );
			System.out.println("Echo server start at port: " + PORT);
			
			while( true )
			{
				// 此方法阻塞,直至有socket的连接请求过来
				Socket clnt = srv.accept();
				
				handleReq(clnt);
			}
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) 
	{
		new TCPEchoServer().start();
	}
}
 

 

客户端:
public class TCPEchoClient {

	JFrame mainFrame;
	
	JPanel container;
	
	JLabel reqLabel;
	
	JLabel resLabel;
	
	JTextField reqTfld;
	
	JTextField resTfld;
	
	JButton sendBtn;
	
	private class SendEchoAction implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			String reqStr = reqTfld.getText();
			
			sendEcho(reqStr);
		}
	}
	
	public void initUI() 
	{
		mainFrame = new JFrame("Echo client");
		
		setCmpt();
		
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		mainFrame.pack();
		
		mainFrame.setLocationRelativeTo(null);
		
		mainFrame.setVisible(true);
	}
	
	private void setCmpt() 
	{
		reqLabel = new JLabel("Input String:");
		resLabel = new JLabel("Server return String:");
		
		reqTfld = new JTextField();
		resTfld = new JTextField();
		
		sendBtn = new JButton("Send");
		
		sendBtn.addActionListener(new SendEchoAction());
		
		container = new JPanel();
		container.setLayout(new GridLayout(2, 3));
		
		container.add(reqLabel);
		container.add(reqTfld);
		container.add(sendBtn);
		
		container.add(resLabel);
		container.add(resTfld);
		
		mainFrame.setLayout(new FlowLayout(FlowLayout.CENTER));
		mainFrame.add(container);
		
	}
	
	public void sendEcho(String echo)
	{
		Socket snd = null;
		try 
		{
			snd = new Socket(TCPEchoServer.ADDR, TCPEchoServer.PORT);
			
			OutputStream out = snd.getOutputStream();
			
			out.write(echo.getBytes());
			
			InputStream in = snd.getInputStream();
			
			byte[] b = new byte[1024];
			
			int len = in.read(b);
			
			String resEcho = new String(b, 0, len); 
			resTfld.setText(resEcho);
		} 
		catch (Exception e1) 
		{
			e1.printStackTrace();
			resTfld.setText(e1.getMessage());
		}
		finally
		{
			if( snd != null )
			{
				try 
				{
					snd.close();
				} 
				catch (IOException e1)
				{
				}
			}
		}
	}
	
	
	public static void main(String[] args) {
		
		TCPEchoClient client = new TCPEchoClient();
		client.initUI();
	}
}
 运行客户端如下:

 
 
 多线程服务器端模型
 为服务器端增加多线程处理连接,因为Java基于TCP的实现具有阻塞特性,若多个Client连接进来却不能并发处理的话,这样效率很低。此处只需server做改动。
示例代码:
服务器端:
public class TCPEchoMultiThreadServer extends TCPEchoServer{

	@Override
	public void handleReq(Socket clnt) throws IOException 
	{
                // 重写此方法,睡它一下,模拟处理延时
		try 
		{
			Thread.sleep(1500L);
		} 
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		super.handleReq(clnt);
	}
	
	@Override
	public void start() 
	{
		try 
		{
			ServerSocket srv = new ServerSocket(PORT, 0, InetAddress.getByName(ADDR));
			System.out.println("Echo multi-thread server start at port: " + PORT);
			
			while( true )
			{
				final Socket clnt = srv.accept();
				
				Thread thread = new Thread( new Runnable() 
					{
						@Override
						public void run() 
						{
							try 
							{
								handleReq(clnt);
							} 
							catch (IOException e) 
							{
								e.printStackTrace();
							}
						}
					}
				);
				
				thread.start();
                                // 打印出线程名字,可以看出每次请求都会新建线程来处理
				System.out.println(thread.getName());
			}
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) 
	{
		new TCPEchoMultiThreadServer().start();
	}
}
  
广播服务器模型
玩Dota, LoL,当中同组的消息列就是属于广播模型
示例代码:
 Server 端:
public class TCPEchoBroadcastServcer{

	public static final int PORT = 7777;
	
	public static final String ADDR = "127.0.0.1";
	
	public static final String LOGIN_CODE = "#login";
	
	public static final String LOGOUT_CODE = "#logout"; 

	public static final String REGISTER_NEED = "#yourID";
	
	public static final String FORMAL_MSG = "#fMsg";
	
	private Map<String, Socket> clntSocketList;
	
	public void start()
	{
		try 
		{
			ServerSocket ss = new ServerSocket( PORT, 0, InetAddress.getByName(ADDR) );
			System.out.println("Echo multi-thread server start at port: " + PORT);
			clntSocketList = new HashMap<String, Socket>();
			
			while( true )
			{
				final Socket clnt = ss.accept();
				
				Thread thread = new Thread( 
					new Runnable() 
					{
						@Override
						public void run() 
						{
							try 
							{
								handleReq(clnt);
							} 
							catch (IOException e) 
							{
								e.printStackTrace();
							}
						}
					}
				);
				
				thread.start();
				
			}
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
	
	protected void handleReq(Socket clnt) throws IOException 
	{
		System.out.println("Client connected from: " + clnt.getInetAddress());
		
		InputStream dataIn = clnt.getInputStream();
		
		byte[] b = new byte[64]; 
		int len = dataIn.read(b);
		String req = new String(b, 0, len);
		
                // 这里实现比较挫,用了几个静态常量去区分消息种类,
                // FORMAL_MSG代表的是普通消息,LOGIN_CODEclient连进server端的消息
                // LOGOUT_CODE是离开server端消息
		if( req.indexOf(FORMAL_MSG) == -1 )
		{
			if( req.indexOf( "["+LOGIN_CODE+"]" ) == 0 )
			{
				String clntId = req.split(":")[1];
				
				clntSocketList.put(clntId, clnt);
				
				req = "New client login";
			}
			else if(  req.indexOf( "["+LOGOUT_CODE+"]" ) == 0 )
			{
				String clntId = req.split(":")[1];
				
				if( clntSocketList.containsKey(clntId) )
				{
					clntSocketList.get(clntId).close();
					clntSocketList.remove(clntId);
				}
				
				req = "A client left";
			}
		}
		else
		{
                        //普通消息需要进行截取字符串,比较挫,但一时想不出好办法。。。
			req = req.substring(req.indexOf(FORMAL_MSG)+FORMAL_MSG.length()+1, req.length());
		}
		
		_sendBroadcastMsg(req);
	}
	
	private synchronized void _sendBroadcastMsg( String msg ) throws IOException
	{
		for( String key: clntSocketList.keySet() )
		{
			Socket clnt = clntSocketList.get(key);
			if( !clnt.isClosed() && clnt.isConnected() )
			{
				this._sendMsg(clnt, msg);
				//out.close();
			}
		}
	}
	
	private void _sendMsg( Socket clnt, String msg ) throws IOException 
	{
		OutputStream out = clnt.getOutputStream();
		
		out.write(msg.getBytes());
	}
	
	public static void main(String[] args) 
	{
		new TCPEchoBroadcastServcer().start();
	}
}
 Client端:
public class TCPEchoBroadcastClient {
	
	private String id;
	
	JFrame mainFrame;
	
	JPanel container;
	
	JPanel row1;
	
	JPanel row2;
	
	JLabel reqLabel;
	
	JLabel resLabel;
	
	JTextField reqTfld;
	
	JTextArea resTArea;
	
	JButton sendBtn;
	
	Socket connSocket;
	
	public TCPEchoBroadcastClient() 
	{
		this.id = UUID.randomUUID().toString();
	}
	
	private class SendEchoAction implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			String reqStr = reqTfld.getText();
			
			sendEcho(reqStr);
		}
	}
	
	private class DisconnectAction extends WindowAdapter
	{
		@Override
		public void windowClosing(WindowEvent e) 
		{
			try 
			{
				_leftServer();
			} 
			catch (IOException e1) {}
			super.windowClosing(e);
		}
	}
	
	public void initUI() 
	{
		mainFrame = new JFrame("Echo Broadcast client");
		
		setCmpt();
		
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		mainFrame.addWindowListener(new DisconnectAction());
		
		//mainFrame.pack();
		mainFrame.setSize(500, 400);
		
		mainFrame.setResizable(false);
		
		mainFrame.setLocationRelativeTo(null);
		
		mainFrame.setVisible(true);
		
		_connectServer();
	}
	
	private void setCmpt() 
	{
		row1 = new JPanel();
		
		reqLabel = new JLabel("Input String:");
		resLabel = new JLabel("Server return String:");
		
		reqTfld = new JTextField();
		resTArea = new JTextArea();
		resTArea.setEditable(false);
		
		sendBtn = new JButton("Send");
		
		sendBtn.addActionListener(new SendEchoAction());
		
		container = new JPanel();
		
		GridBagLayout layout = new GridBagLayout();
		container.setLayout(layout);
	
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.BOTH;
		gbc.insets = new Insets(2, 2, 2, 2);
		
		gbc.weightx = 1;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		layout.setConstraints(reqLabel, gbc);
		container.add(reqLabel);
		
		gbc.weightx = 1;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.ipadx = 220;
		layout.setConstraints(reqTfld, gbc);
		container.add(reqTfld);
		
		gbc.weightx = 1;
		gbc.gridwidth = 0;
		gbc.gridheight = 1;
		gbc.ipadx = 0;
		layout.setConstraints(sendBtn, gbc);
		container.add(sendBtn);
		
		JPanel resLbPanel = new JPanel();
		resLbPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		resLbPanel.add(resLabel);
		
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		layout.setConstraints(resLbPanel, gbc);
		container.add(resLbPanel);
		
		JScrollPane resTaPanel = new JScrollPane(resTArea);
		resTaPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		resTaPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		
		gbc.weighty = 1;
		gbc.gridwidth = 0;
		gbc.gridheight = 1;
		layout.setConstraints(resTaPanel, gbc);
		container.add(resTaPanel);
		
		mainFrame.add(container);
	}
	
	private void _connectServer()
	{
		try 
		{
			connSocket = new Socket(TCPEchoBroadcastServcer.ADDR, TCPEchoBroadcastServcer.PORT);
			
			this._registerToServer();
			
			Thread thread = new Thread(new Runnable() 
				{
					@Override
					public void run() 
					{
						try 
						{
							while( true )
							{
								_listenToServer();
							}
						} 
						catch (IOException e) 
						{
							e.printStackTrace();
						}
					}
				}
			);
			
			thread.start();
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
			if( connSocket != null )
			{
				try 
				{
					connSocket.close();
				} 
				catch (IOException ie) {}
			}
		} 
	}
	
	private void _registerToServer() throws IOException
	{
		OutputStream out = connSocket.getOutputStream();
		
		String reqStr = "[" + TCPEchoBroadcastServcer.LOGIN_CODE + "]:" + this.id;
		out.write(reqStr.getBytes());
		
		out.flush();
	}
	
	private void _leftServer() throws IOException
	{
		Socket snd = new Socket(TCPEchoBroadcastServcer.ADDR, TCPEchoBroadcastServcer.PORT);
		
		OutputStream out = snd.getOutputStream();
		
		String reqStr = "[" + TCPEchoBroadcastServcer.LOGOUT_CODE + "]:" + this.id;
		out.write(reqStr.getBytes());
		
		out.flush();
		
		snd.close();
	}
	
	private void _listenToServer() throws IOException
	{
		if( connSocket.isClosed() )
		{
			return;
		}
		
		String resStr = null;
		
		InputStream in = connSocket.getInputStream();
		
		byte[] b = new byte[64];
		int len = in.read(b);
		if( len != -1 )
		{
			resStr = new String(b, 0, len);
			
			resTArea.append(resStr+"\n");
		}
	}
	
	public void sendEcho(String echo)
	{
		Socket snd = null;
		try 
		{
			snd = new Socket(TCPEchoBroadcastServcer.ADDR, TCPEchoBroadcastServcer.PORT);
			
			OutputStream out = snd.getOutputStream();
			
			echo = TCPEchoBroadcastServcer.FORMAL_MSG + ":" + echo;
			out.write(echo.getBytes());
			
			out.flush();
			
		} 
		catch (Exception e1) 
		{
			e1.printStackTrace();
		}
		finally
		{
			if( snd != null )
			{
				try 
				{
					snd.close();
				} 
				catch (IOException e1){}
			}
		}
	}
	
	public static void main(String[] args) 
	{
		TCPEchoBroadcastClient client = new TCPEchoBroadcastClient();
		client.initUI();
	}
}
 

 
UDP通讯方式
最后是基于UDP传输协议的一个demo,具体应用场景还不太清楚。。。
Server 端:
public class UDPEchoServer {

	public static final int PORT = 7777;
	public static final String ADDR = "127.0.0.1";
	
	public static void main(String[] args) {
		
		DatagramSocket srv = null;
		try 
		{
			byte[] buffer = new byte[1024];
			
			srv = new DatagramSocket(PORT);
			
			DatagramPacket packet = new DatagramPacket(buffer, 1024);
			System.out.println("Server is ready, Waiting requset come...");
			
			while( true )
			{
				srv.receive(packet);
				
				InetAddress clntAddr = packet.getAddress();
				
				int clntPort = packet.getPort();
				
				System.out.println("A request package from: " + clntAddr + " # " + clntPort);
				
				String str = new String(packet.getData());
				
				String echo = str.toUpperCase();
				
				DatagramPacket resPacket = new DatagramPacket(echo.getBytes(), echo.length(), clntAddr, clntPort);
				
				srv.send(resPacket);
			}
		} 
		catch (Exception e) 
		{
			if( srv != null )
			{
				srv.close();
			}
		}
	}
}
 
客户端:
public class UDPEchoClient {

JFrame mainFrame;
	
	JPanel container;
	
	JLabel reqLabel;
	
	JLabel resLabel;
	
	JTextField reqTfld;
	
	JTextField resTfld;
	
	JButton sendBtn;
	
	private class SendEchoAction implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			String reqStr = reqTfld.getText();
			
			sendEcho(reqStr);
		}
	}
	
	public void initUI() 
	{
		mainFrame = new JFrame("Echo client");
		
		setCmpt();
		
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		mainFrame.pack();
		
		mainFrame.setLocationRelativeTo(null);
		
		mainFrame.setVisible(true);
	}
	
	private void setCmpt() 
	{
		reqLabel = new JLabel("Input String:");
		resLabel = new JLabel("Server return String:");
		
		reqTfld = new JTextField();
		resTfld = new JTextField();
		
		sendBtn = new JButton("Send");
		
		sendBtn.addActionListener(new SendEchoAction());
		
		container = new JPanel();
		container.setLayout(new GridLayout(2, 3));
		
		container.add(reqLabel);
		container.add(reqTfld);
		container.add(sendBtn);
		
		container.add(resLabel);
		container.add(resTfld);
		
		mainFrame.setLayout(new FlowLayout(FlowLayout.CENTER));
		mainFrame.add(container);
		
	}
	
	public void sendEcho(String echo)
	{
		DatagramSocket clnt = null;
		
		try 
		{
			clnt = new DatagramSocket();
			
			byte[] sndEcho =  echo.getBytes();
			
			InetAddress addr = InetAddress.getByName(UDPEchoServer.ADDR);
			
			DatagramPacket packet = new DatagramPacket(sndEcho, sndEcho.length, addr, UDPEchoServer.PORT);
			
			clnt.send(packet);
			
			clnt.receive(packet);
			
			byte[] resData =  packet.getData();
			
			resTfld.setText(new String(resData));
		} 
		catch (Exception e) 
		{
			clnt.close();
		}
	}
	
	public static void main(String[] args) 
	{
		UDPEchoClient client = new UDPEchoClient();
		
		client.initUI();
	}
}
 
  • 大小: 11.2 KB
  • 大小: 40.6 KB
分享到:
评论

相关推荐

    Java TCP IP Socket编程(原书第2版).

    《Java TCP/IP Socket编程(原书第2版)》基于TCP/IP Socket相关原理,对如何在Java中进行Socket...《Java TCP/IP Socket编程(原书第2版)》适合作为Java Socket编程的入门教程,也可供从事网络相关专业的技术人员参考。

    java_socket_simple_Server.rar_java socket _socket java

    极好的java网络编程入门示例. 注释详尽规范,架构优秀。 不可多得!

    java的入门教程

    从基本的数据类型到 类的继承重载和复写都比较详细,还有java的常用类库的介绍,多线程的介绍,同步异步,还有异常的捕获讲解都叫基础详细,网络编程基础socket的介绍附有一定的代码示例,很适合初学者

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    11.2.1 ServerSocket与Socket示例: 开发一个Server-Client模型的程序 291 11.2.2 多点传送示例 293 11.2.3 打造你自己的QQ 295 11.3 小结 315 第12章 找个好管家——JMX 317 12.1 讲解 318 12.1.1 什么是 JMX...

    JAVA上百实例源码以及开源项目

    Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例...

    JAVA上百实例源码以及开源项目源代码

    Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例...

    JAVA基础课程讲义

    第一章 JAVA入门 10 计算机语言发展史 10 机器语言 10 汇编语言 10 高级语言 10 其他高级语言 11 JAVA发展简史 12 JAVA为什么能够流行? 13 JAVA各版本的含义 13 JAVA技术体系架构 14 JAVA的特性和优势 14 JAVA应用...

    安卓入门DEMO集合

    本集合是经过网上收集,入门学习的时候一步一步积累...SortListViewDemo和ListViewDemo: LIST 安卓核心组件入门好示例 GPSDemo: 安卓下使用GPS定位的示例代码 WeixinDemo:学习完了上述的,来个好的仿微信的社交示例

    socket.io.play:具有播放框架2.0的socket.io

    用于游戏的socket.io!...最简单的入门方法是查看示例应用程序。 手动步骤: 下面提到的仓库可能不会被更新,因此最好在本地进行编译和发布。 将Sonatype OSS存储库添加到您的Play框架 val main = PlayProject

    [14本经典Android开发教程]-7-Android编程入门教程

    [14本经典Android开发教程]-7-...10个C#Socket编程代码示例 http://download.csdn.net/album/detail/631 6份GDI+程序设计资源整合[全零分] http://download.csdn.net/album/detail/625 2014年移动游戏行业数据分析 ...

    Java开发技术大全 电子版

    第1篇Java基础知识入门. 第1章Java的开发运行环境2 1.1Java的运行环境与虚拟机2 1.2Java的开发环境4 1.2.1JDK的安装4 1.2.2如何设置系统环境变量6 1.2.3编译命令的使用8 1.2.4解释执行命令的使用10 1.2.5...

    java自学之道

    1.1 面向对象程序设计入门分析 1.2 抽象 1.3 封装 2、类 2.1 类头 2.2类体 2.3 创建对象 2.4 面向对象举例 2.5 构造函数 2.5.1 构造函数的一般概念 2.5.2 创建自己的构造函数 2.5.3 构造方法注意事项 2.5.4构造...

    Android游戏源码—3D迷宫

    Android游戏源码-3D迷宫 ...10个C#Socket编程代码示例 http://download.csdn.net/album/detail/631 6份GDI+程序设计资源整合[全零分] http://download.csdn.net/album/detail/625 2014年移动游戏行业数据分析 ...

    python3.6.0入门指南(官方版)

    这些模块提供了诸如文件 I/O 、系统调用、 Socket 支持,甚至类似 Tk 的用户图形 界面( GUI )工具包接口。 Python 是一门解释型语言,因为无需编译和链接,你可以在程序开发中节省宝贵的时间。 Python 解释器可以...

    C#摄像头源码

    10个C#Socket编程代码示例 http: download csdn net album detail 631 6份GDI+程序设计资源整合[全零分] http: download csdn net album detail 625"&gt;Cocos2d x 消灭星星源码 PopStar @更多@ ...

    Cocos2d-x 消灭星星源码 PopStar

    10个C#Socket编程代码示例 http: download csdn net album detail 631 6份GDI+程序设计资源整合[全零分] http: download csdn net album detail 625"&gt;Cocos2d x 消灭星星源码 PopStar @更多@ ...

    [14本经典Android开发教程]-2-Android开发手册—API函数详解

    [14本经典Android开发教程] 2 ...10个C#Socket编程代码示例 http: download csdn net album detail 631 6份GDI+程序设计资源整合[全零分] http: download csdn net album detail 625 2014年移动游戏行业数据分析 ...

    WPF自定义控件开发Sample

    10个C#Socket编程代码示例 http://download.csdn.net/album/detail/631 6份GDI+程序设计资源整合[全零分] http://download.csdn.net/album/detail/625 更多免费资源 http://download.csdn.net/user/cleopard

    Android C++高级编程:使用NDK_Onur Cinar, 于红PDF电子书下载 带书签目录 完整版

    7.2.1 修改示例应用程序使之能够使用Java线程 165 7.2.2 执行Java Threads示例 166 7.2.3 原生代码使用Java线程的优缺点 167 7.3 POSIX线程 168 7.3.1 在原生代码中使用POSIX线程 168 7.3.2 用pthread_create...

Global site tag (gtag.js) - Google Analytics