精华内容
下载资源
问答
  • SuperSocket实例程序

    2018-03-20 22:29:46
    基于SuperSocket V1.6.1开发的示例程序,含服务端和客户端,编译无报错,运行正常。学习基于SuperSocket开发的同学值得一看
  • Socket编程

    千次阅读 多人点赞 2019-04-19 15:12:04
    文章目录Socket编程一、计算机网络基础知识1、两台计算机间进行通讯需要以下三个条件:2、TCP/IP协议:3、TCP/IP四层模型4、IP地址5、端口6、Socket套接字:7、Java中的网络支持二、TCP编程1、TCP协议2、Java中基于...

    Socket编程

      在网络编程中,使用最多的就是Socket。像大家熟悉的QQ、MSN都使用了Socket相关的技术。

    一、计算机网络基础知识

      关于计算机网络基础知识可以参考博客:
      https://blog.csdn.net/u014644574/article/details/89301205

    1、两台计算机间进行通讯需要以下三个条件:

      IP地址、协议、端口号

    2、TCP/IP协议:

      TCP/IP是目前世界上应用最为广泛的协议,是以TCP和IP为基础的不同层次上多个协议的集合,也称TCP/IP协议族、或TCP/IP协议栈

    • TCP:Transmission Control Protocol 传输控制协议
    • IP:Internet Protocol 互联网协议

    3、TCP/IP四层模型

    • 应用层:HTTP、FTP、POP3、SMTP、Telnet、SSH、DNS等
    • 传输层:TCP/UDP
    • 网络层:IP
    • 网络接口层: 包括数据链路层(负责网络寻址)和物理层(通过物理介质:双绞线、光纤等传输二进制数据)

    4、IP地址

      为实现网络中不同计算机之间的通信,每台计算机都必须有一个唯一的标识—IP地址。使用32位二进制表示。

    5、端口

      区分一台主机的多个不同应用程序,端口号范围为0-65535,其中0-1023位为系统保留。
      如:HTTP:80 FTP:21 Telnet:23
      IP地址+端口号组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础

    6、Socket套接字:

      网络上具有唯一标识的IP地址和端口组合在一起才能构成唯一能识别的标识符套接字。

      Socket原理机制:

    • 通信的两端都有Socket
    • 网络通信其实就是Socket间的通信
    • 数据在两个Socket间通过IO传输

    7、Java中的网络支持

      针对网络通信的不同层次,Java提供了不同的API,其提供的网络功能有四大类:

    • InetAddress:用于标识网络上的硬件资源,主要是IP地址
    • URL:统一资源定位符,通过URL可以直接读取或写入网络上的数据
    • Sockets:使用TCP协议实现的网络通信Socket相关的类
    • Datagram:使用UDP协议,将数据保存在用户数据报中,通过网络进行通信。

    二、TCP编程

    1、TCP协议

      是面向连接的、可靠的、有序的、以字节流的方式发送数据,通过三次握手方式建立连接,形成传输数据的通道,在连接中进行大量数据的传输,效率会稍低

    2、Java中基于TCP协议实现网络通信的类

      客户端的Socket类
      服务器端的ServerSocket类

    3、Socket通信的步骤

    • ① 创建ServerSocket和Socket
    • ② 打开连接到Socket的输入/输出流
    • ③ 按照协议对Socket进行读/写操作
    • ④ 关闭输入输出流、关闭Socket

    4、服务器端:

    • ① 创建ServerSocket对象,绑定监听端口
    • ② 通过accept()方法监听客户端请求
    • ③ 连接建立后,通过输入流读取客户端发送的请求信息
    • ④ 通过输出流向客户端发送相应信息
    • ⑤ 关闭相关资源
    // 服务端
    // 1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
    ServerSocket serverSocket = new ServerSocket(10086);// 1024-65535的某个端口
    // 2、调用accept()方法开始监听,等待客户端的连接
    Socket socket = serverSocket.accept();
    // 3、获取输入流,并读取客户端信息
    InputStream is = socket.getInputStream();
    InputStreamReader isr = new InputStreamReader(is, "utf-8");
    BufferedReader br = new BufferedReader(isr);
    String info = null;
    while ((info = br.readLine()) != null) {
    	System.out.println("我是服务器,客户端说:" + info);
    }
    socket.shutdownInput();// 关闭输入流
    // 4、获取输出流,响应客户端的请求
    OutputStream os = socket.getOutputStream();
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "utf-8"));
    pw.write("欢迎您!");
    pw.flush();
    // 5、关闭资源
    pw.close();
    os.close();
    br.close();
    isr.close();
    is.close();
    socket.close();
    serverSocket.close();
    

    5、客户端:

    • ① 创建Socket对象,指明需要连接的服务器的地址和端口号
    • ② 连接建立后,通过输出流想服务器端发送请求信息
    • ③ 通过输入流获取服务器响应的信息
    • ④ 关闭响应资源
    // 客户端
    // 1、创建客户端Socket,指定服务器地址和端口
    Socket socket = new Socket("192.168.9.128", 10086);
    // 2、获取输出流,向服务器端发送信息
    OutputStream os = socket.getOutputStream();// 字节输出流
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "utf-8"));// 将输出流包装成打印流
    pw.write("用户名:admin;密码:123");
    pw.flush();
    socket.shutdownOutput();
    // 3、获取输入流,并读取服务器端的响应信息
    InputStream is = socket.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
    String info = null;
    while ((info = br.readLine()) != null) {
    	System.out.println("我是客户端,服务器说:" + info);
    }
    // 4、关闭资源
    br.close();
    is.close();
    pw.close();
    os.close();
    socket.close();  
    

    6、应用多线程实现服务器与多客户端之间的通信

    • ① 服务器端创建ServerSocket,循环调用accept()等待客户端连接
    • ② 客户端创建一个socket并请求和服务器端连接
    • ③ 服务器端接受苦读段请求,创建socket与该客户建立专线连接
    • ④ 建立连接的两个socket在一个单独的线程上对话
    • ⑤ 服务器端继续等待新的连接
    package socket;
    
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     * 多线程服务端
     */
    public class ServerThread extends Thread {
    
    	private Socket socket = null;
    
    	public ServerThread(Socket socket) {
    		this.socket = socket;
    	}
    
    	@Override
    	public void run() {
    		try {
    			// 3、获取输入流,并读取客户端信息
    			InputStream is = socket.getInputStream();
    			InputStreamReader isr = new InputStreamReader(is, "utf-8");
    			BufferedReader br = new BufferedReader(isr);
    			String info = null;
    			while ((info = br.readLine()) != null) {
    				System.out.println("我是服务器,客户端说:" + info);
    			}
    			socket.shutdownInput();// 关闭输入流
    			// 4、获取输出流,响应客户端的请求
    			OutputStream os = socket.getOutputStream();
    			PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "utf-8"));
    			pw.write("欢迎您!");
    			pw.flush();
    			// 5、关闭资源
    			pw.close();
    			os.close();
    			br.close();
    			isr.close();
    			is.close();
    			socket.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    	}
    
    	public static void main(String[] args) {
    		try {
    
    			// 服务器代码
    			ServerSocket serverSocket = new ServerSocket(10086);
    			Socket socket = null;
    			int count = 0;// 记录客户端的数量
    			while (true) {
    				socket = serverSocket.accept();
    				ServerThread thread = new ServerThread(socket);
    				thread.start();
    				count++;
    				System.out.println("客户端连接的数量:" + count);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    	}
    }
      
    

    三、UDP编程

      UDP协议(用户数据报协议)是无连接的、不可靠的、无序的,速度快,进行数据传输时,首先将要传输的数据定义成数据报(Datagram),大小限制在64k,在数据报中指明数据索要达到的Socket(主机地址和端口号),然后再将数据报发送出去
      DatagramPacket类:表示数据报包
      DatagramSocket类:进行端到端通信的类

    1、服务器端实现步骤

    • ① 创建DatagramSocket,指定端口号
    • ② 创建DatagramPacket
    • ③ 接受客户端发送的数据信息
    • ④ 读取数据
    	// 服务器端,实现基于UDP的用户登录
    	// 1、创建服务器端DatagramSocket,指定端口
    	DatagramSocket socket = new DatagramSocket(10010);
    	// 2、创建数据报,用于接受客户端发送的数据
    	byte[] data = new byte[1024];
    	DatagramPacket packet = new DatagramPacket(data, data.length);
    	// 3、接受客户端发送的数据
    	socket.receive(packet);// 此方法在接受数据报之前会一致阻塞
    	// 4、读取数据
    	String info = new String(data, 0, packet.getLength(), "utf-8");
    	System.out.println("我是服务器,客户端告诉我:" + info);
    	
    	// =========================================================
    	// 向客户端响应数据
    	// 1、定义客户端的地址、端口号、数据
    	InetAddress address = packet.getAddress();
    	int port = packet.getPort();
    	byte[] data2 = "欢迎您!".getBytes("utf-8");
    	// 2、创建数据报,包含响应的数据信息
    	DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
    	// 3、响应客户端
    	socket.send(packet2);
    	// 4、关闭资源
    	socket.close();
    

    2、客户端实现步骤

    • ① 定义发送信息
    • ② 创建DatagramPacket,包含将要发送的信息
    • ③ 创建DatagramSocket
    • ④ 发送数据
    	// 客户端
    	// 1、定义服务器的地址、端口号、数据
    	InetAddress address = InetAddress.getByName("192.168.9.128");
    	int port = 10010;
    	byte[] data = "用户名:admin;密码:123".getBytes("utf-8");
    	// 2、创建数据报,包含发送的数据信息
    	DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
    	// 3、创建DatagramSocket对象
    	DatagramSocket socket = new DatagramSocket();
    	// 4、向服务器发送数据
    	socket.send(packet);
    
    	// 接受服务器端响应数据
    	// ======================================
    	// 1、创建数据报,用于接受服务器端响应数据
    	byte[] data2 = new byte[1024];
    	DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
    	// 2、接受服务器响应的数据
    	socket.receive(packet2);
    	String reply = new String(data2, 0, packet2.getLength(), "utf-8");
    	System.out.println("我是客户端,服务器说:" + reply);
    	// 4、关闭资源
    	socket.close();
    

    四、注意问题:

    1、多线程的优先级问题:
      根据实际的经验,适当的降低优先级,否侧可能会有程序运行效率低的情况
    2、是否关闭输出流和输入流:
      对于同一个socket,如果关闭了输出流,则与该输出流关联的socket也会被关闭,所以一般不用关闭流,直接关闭socket即可
    3、使用TCP通信传输对象,IO中序列化部分
    4、socket编程传递文件,IO流部分

    展开全文
  • 获取计算机的名称和IP地址可以通过调用winsock里面的函数完成,下面上是用到的函数:1.WSAStartup(),此函数在应用程序中初始化windows sockets DLL,这个函数调用成功后,才可以调用其他的api函数。 2.WSACleanup()...

    获取计算机的名称和IP地址可以通过调用winsock里面的函数完成,下面上是用到的函数:1.WSAStartup(),此函数在应用程序中初始化windows sockets DLL,这个函数调用成功后,才可以调用其他的api函数。

    2.WSACleanup()函数,应用程序会占用系统资源,这个函数用来解除与socket的绑定,并且释放占用的系统资源。

    3.gethostname() 用于获取本地主机的主机名

    4.gethostbyname()gethostname()获取的主机名可以传入gethostbyname,获取“主机列表”。一台主机可以有多个IP地址,为了输出所有IP地址,要用一个循环来实现。

    #include "stdafx.h"
    #include <iostream>  
    using namespace std;  
    #include "winsock2.h"  
    #pragma comment(lib,"ws2_32.lib")  
    int main()  
    {  
    WSAData data;  
    if(WSAStartup(MAKEWORD(1,1),&data)!=0)  
    {  
       cout<<"初始化错误endl" ;  
    }  
        
    char host[255];  
    if(gethostname(host,sizeof(host))==SOCKET_ERROR)  
    {  
       cout<<"无法获取主机名"<<endl;  
    }  
    else  
    {  
       cout<<"本机计算机名为:"<<host<<endl;  
    }  
      
    struct hostent *p=gethostbyname(host);  
    if(p==0)  
    {  
       cout<<"无法获取计算机主机名及IP"<<endl;  
    }  
    else  
    {  
        cout<<p->
       //本机IP:利用循环,输出本机所有IP  
       for(int i=0;p->h_addr_list[i]!=0;i++)  
       {  
        struct in_addr in;  
        memcpy(&in,p->h_addr_list[i],sizeof(struct in_addr));  
        cout<<"第"<<i+1<<"块网卡的IP为:"<<inet_ntoa(in)<<endl;  
       }  
      
    }  
      
    WSACleanup();  
      
    cin.get();  
    return 0;  
    }  

    上面的代码中,gethostbyname的返回值送入了hostent结构体中,hostent结构体在winsock2.h中声明

     hostent的定义如下:

    struct hostent{

    char *h_name;

    char **h_aliases;

    int h_addrtype;

    int h_length;

    char **h_addr_list;

    # define h_addr h_addr_list[0];

    };

    h_name   为地址名称

    h_aliases 地址的预备名称指针

    h_addtype  地址类型

    h_length   地址的长度

    h_addr_list  主机网络地址指针

    h_addr   h_add_list 的第一个地址

    gethostname:  是获取本机的所有的IP地址。

    还有一个:getsockname:  是获取跟某一特定的socket相关的IP地址。

    getsockname方式来获取对应的 IP地址的时候,首先需要通过socket函数创建的有效的套接字,另外还要bind。才能执行成功。如果在socket和bind之间调用就会调用失 败。虽然在bind之后可以执行成功,通常我们得到的结果是0.0.0.0,除非在bind的时候就指定特定的IP。

    如果想获取本机所有网卡的信息,当然也包括IP的信息。可以通过GetAdaptersInfo这个windows API。区别于上述方法的是,这个函数只能在windows上面,前面两个在windows和linux上面都可以。

    GetAdaptersInfo:

      在win下时,如果不只想单单获取ip地址,还要分清这个ip地址对应哪个网卡时,就需要这个了。

       windows sdk中,用IP_ADAPTER_INFO结构体存储网卡信息,包括网卡名、网卡描述、网卡MAC地址、网卡IP等,结构体结构如下:

    typedef struct _IP_ADAPTER_INFO {
      struct _IP_ADAPTER_INFO* Next;//指向链表中下一个适配器信息的指针
      DWORD ComboIndex;//预留值
      char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//使用ANSI字符串表示的适配器名称
      char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//使用ANSI字符串表示的适配器描述
      UINT AddressLength;//适配器硬件地址以字节计算的长度
      BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];//硬件地址以BYTE数组所表示
      DWORD Index;//适配器索引
        UINT Type;//适配器类型,主要有以下几种:
        /*
         *   MIB_IF_TYPE_OTHER     1
         *   MIB_IF_TYPE_ETHERNET     6
         *   MIB_IF_TYPE_TOKENRING     9
         *   MIB_IF_TYPE_FDDI     15
         *   MIB_IF_TYPE_PPP     23
         *   MIB_IF_TYPE_LOOPBACK      24
         *   MIB_IF_TYPE_SLIP      28
         */
      UINT DhcpEnabled;//指定这个适配器是否开启DHCP
      PIP_ADDR_STRING CurrentIpAddress;//预留值
      IP_ADDR_STRING IpAddressList;//该适配器的IPv4地址链表
      IP_ADDR_STRING GatewayList;//该适配器的网关IPv4地址链表
      IP_ADDR_STRING DhcpServer;//该适配器的DHCP服务器的IPv4 地址链表
      BOOL HaveWins;
      IP_ADDR_STRING PrimaryWinsServer;
      IP_ADDR_STRING SecondaryWinsServer;
      time_t LeaseObtained;
      time_t LeaseExpires;
      } IP_ADAPTER_INFO,*PIP_ADAPTER_INFO;

       由于可能有多个网卡,因此struct _IP_ADAPTER_INFO* Next字段为一个链表结构指针,由于一个网卡可能有多个IP,因此IP_ADDR_STRING字段应该也是一个链表结构,结构如下:

    typedef struct _IP_ADDR_STRING
    {
        struct _IP_ADDR_STRING* Next;  //指向同类型节点,即下一个IP(如果有多IP的话)
        IP_ADDRESS_STRING IpAddress;  //IP地址信息
        IP_MASK_STRING IpMask; //IP子网掩码
        DWORD Context;// 网络表入口。这个值对应着AddIPAddredd和DeleteIPAddress函数中的NTEContext参数
    } IP_ADDR_STRING;

     代码如下:参考http://www.oschina.net/code/snippet_222150_19528#32487

    // AllTest.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <WinSock2.h>
    #include <Iphlpapi.h>
    #include <iostream>
    #include <vector>
    using namespace std;
    #pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库
     
    int main(int argc, char* argv[])
    {
    	vector<char*> ip;
        //PIP_ADAPTER_INFO结构体指针存储本机网卡信息
        PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
        //得到结构体大小,用于GetAdaptersInfo参数
        unsigned long stSize = sizeof(IP_ADAPTER_INFO);
        //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量
        int nRel = GetAdaptersInfo(pIpAdapterInfo,&stSize);
        //记录网卡数量
        int netCardNum = 0;
        //记录每张网卡上的IP地址数量
        int IPnumPerNetCard = 0;
        if (ERROR_BUFFER_OVERFLOW == nRel)
        {
            //如果函数返回的是ERROR_BUFFER_OVERFLOW
            //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
            //这也是说明为什么stSize既是一个输入量也是一个输出量
            //释放原来的内存空间
            delete pIpAdapterInfo;
            //重新申请内存空间用来存储所有网卡信息
            pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
            //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
            nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize);    
        }
    	if (ERROR_SUCCESS == nRel)
    	{
    		//控制无线网卡的多读入
    		int i=1;
    		//输出网卡信息
    		//可能有多网卡,因此通过循环去判断
    		while (pIpAdapterInfo)
    		{
    			cout<<"网卡描述:"<<pIpAdapterInfo->Description<<endl;
    			switch (pIpAdapterInfo->Type)
    			{
    			case MIB_IF_TYPE_OTHER:
    				break;
    			case MIB_IF_TYPE_ETHERNET:
    				{
    					//可能网卡有多IP,因此通过循环去判断
    					IP_ADDR_STRING *pIpAddrString =&(pIpAdapterInfo->IpAddressList);
    					do
    					{
    						//IP 地址:
    						while (ip.size()<2) ip.push_back("");
    							if (strcmp(pIpAddrString->IpAddress.String,"0.0.0.0")!=0&&strstr(pIpAdapterInfo->Description,"PCI"))
    								ip[1]=pIpAddrString->IpAddress.String;
    						//"子网地址:"pIpAddrString->IpMask.String
    						//"网关地址:"pIpAdapterInfo->GatewayList.IpAddress.String
    						pIpAddrString=pIpAddrString->Next;
    					} while (pIpAddrString);
    				}
    				break;
    			case MIB_IF_TYPE_TOKENRING:
    				break;
    			case MIB_IF_TYPE_FDDI:
    				break;
    			case MIB_IF_TYPE_PPP:
    				break;
    			case MIB_IF_TYPE_LOOPBACK:
    				break;
    			case MIB_IF_TYPE_SLIP:
    				break;
    			default://无线网卡在这里,Unknown type
    				{
    					IP_ADDR_STRING *pIpAddrString =&(pIpAdapterInfo->IpAddressList);
    					do
    					{
    						//IP 地址:
    						if (i++==1&&strcmp(pIpAddrString->IpAddress.String,"0.0.0.0")!=0&&strstr(pIpAdapterInfo->Description,"Wireless"))
    						{
    							while (ip.size()<1) ip.push_back("");
    							ip[0]=pIpAddrString->IpAddress.String;
    						}
    						else if (i!=2&&strcmp(pIpAddrString->IpAddress.String,"0.0.0.0")!=0&&strstr(pIpAdapterInfo->Description,"Wireless"))
    							ip.push_back(pIpAddrString->IpAddress.String);
    						//"子网地址:"pIpAddrString->IpMask.String
    						//"网关地址:"pIpAdapterInfo->GatewayList.IpAddress.String
    						pIpAddrString=pIpAddrString->Next;
    					} while (pIpAddrString);
    				}
    				break;
    			}
    	/*		cout<<"网卡MAC地址:"; pIpAdapterInfo->Address[i]);mac地址。*/
    				pIpAdapterInfo = pIpAdapterInfo->Next;
    		}
    
    	}
    	for (int i=0;i<ip.size();i++)
    		cout<<ip[i]<<endl;
    	//释放内存空间
    	if (pIpAdapterInfo)
    	{
    		delete pIpAdapterInfo;
    	}
    	system("pause");
    	return 0;
    }


    与某个套接字关联的外地协议地址即得到对方的地址(getpeername),getpeername只有在连接建立以后才调用,否则不能正确获得对方地址和端口。

    返回与某个套接字关联的本地协议地址(getsockname)

    需要这两个函数的理由如下:

    •   在一个没有调用bind的TCP客户上,connect成功返回后,getsockname用于返回由内核赋予该连接的本地IP地址和本地端口号(自动分配的),没有连接的UDP不能调用getpeername,但是可以调用getsockname和TCP一样,它的地址和端口不是在调用socket就指定了,而是在第一次调用sendto函数以后。

    •   在以端口号为0调用bind(告知内核去选择本地临时端口号)后,getsockname用于返回由内核赋予的本地端口号。

    •   在一个以通配IP地址调用bind的TCP服务器上,与某个客户的连接一旦建立(accept成功返回),getsockname就可以用于返回由内核赋予该连接的本地IP地址。在这样的调用中,套接字描述符参数必须是已连接套接字的描述符,而不是监听套接字的描述符。

    •   当一个服务器的是由调用过accept的某个进程通过调用exec执行程序时,它能够获取客户身份的唯一途径便是调用getpeername。





    展开全文
  • socket获取本机IP地址方法

    万次阅读 2014-02-07 00:43:33
    获取计算机的名称和IP地址可以通过调用winsock里面的函数完成,下面上是用到的函数:1.WSAStartup(),此函数在应用程序中初始化windows sockets DLL,这个函数调用成功后,才可以调用其他的api函数。...

        获取计算机的名称和IP地址可以通过调用winsock里面的函数完成,下面上是用到的函数:1.WSAStartup(),此函数在应用程序中初始化windows sockets DLL,这个函数调用成功后,才可以调用其他的api函数。

    2.WSACleanup()函数,应用程序会占用系统资源,这个函数用来解除与socket的绑定,并且释放占用的系统资源。

    3.gethostname() 用于获取本地主机的主机名

    4.gethostbyname()gethostname()获取的主机名可以传入gethostbyname,获取“主机列表”。一台主机可以有多个IP地址,为了输出所有IP地址,要用一个循环来实现。

    #include <iostream>
    using namespace std;
    #include "winsock2.h"
    #pragma comment(lib,"ws2_32.lib")
    int main()
    {
    WSAData data;
    if(WSAStartup(MAKEWORD(1,1),&data)!=0)
    {
       cout<<"初始化错误endl ;
    }
      
    char host[255];
    if(gethostname(host,sizeof(host))==SOCKET_ERROR)
    {
       cout<<"无法获取主机名"<<endl;
    }
    else
    {
       cout<<"本机计算机名为:"<<host<<endl;
    }
    
    struct hostent *p=gethostbyname(host);
    if(p==0)
    {
       cout<<"无法获取计算机主机名及IP"<<endl;
    }
    else
    {
         
       //本机IP:利用循环,输出本机所有IP
       for(int i=0;p->h_addr_list[i]!=0;i++)
       {
        struct in_addr in;
        memcpy(&in,p->h_addr_list[i],sizeof(struct in_addr));
        cout<<"第"<<i+1<<"块网卡的IP为:"<<inet_ntoa(in)<<endl;
       }
    
    }
    
    WSACleanup();
    
    cin.get();
    return 0;
    }
    
    
    
    

    上面的代码中,gethostbyname的返回值送入了hostent结构体中,hostent结构体在winsock2.h中声明

     hostent的定义如下:

    struct hostent{

    char *h_name;

    char **h_aliases;

    int h_addrtype;

    int h_length;

    char **h_addr_list;

    # define h_addr h_addr_list[0];

    };

    h_name   为地址名称

    h_aliases 地址的预备名称指针

    h_addtype  地址类型

    h_length   地址的长度

    h_addr_list  主机网络地址指针

    h_addr   h_add_list 的第一个地址


    展开全文
  • 简单socket聊天小程序+socket简单封装

    千次阅读 2018-09-02 18:00:11
    一、单线程简单socket聊天小程序 二、windows socket套接字简单封装 三、IP地址的表示形式与各个转换函数 一、单线程简单socket聊天小程序 客户端 #include&amp;amp;lt;WinSock2.h&amp;amp;gt;...

    本博客内容:
    一、单线程简单socket聊天小程序
    二、windows socket套接字简单封装
    三、IP地址的表示形式与各个转换函数
    #一、单线程简单socket聊天小程序
    ###客户端

    #include<WinSock2.h>
    #include<stdio.h>
    
    //定义程序中使用的常量
    #define SERVER_ADDRESS "127.0.0.1" //服务器端IP地址
    #define PORT    5150    //服务器端的端口号
    #define MSGSIZE 1024  //收发缓冲区的大小
    
    //库文件
    #pragma comment(lib,"ws2_32.lib")
    
    int main()
    {
    //1.初始化
    	//该结构体包含系统所支持的winsock版本信息
    	WSADATA wsaData; 
    	//初始化Winsock2.2
    	if(WSAStartup(0x0202,&wsaData)!=0)  //WSAStartup(MAKWWORD(2,2),&wsaData)
    	{
    		printf("无法初始化!"); return 0;
    	}
    //2.socket套接字
    	//定义客户端连接所用的套接字
    	SOCKET sClient;  
    	//参数1:TCP/IP协议族,参数2:TCP协议,UDP使用SOCK_DGRAM 
    	sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    
    	if(sClient==INVALID_SOCKET)
    	{
    			printf("socket failed");
    			return 0;
    	}
    //3.远端服务器
    	//保存远端服务器地址
    	SOCKADDR_IN server; 
    	//置0操作
    	memset(&server,0,sizeof(SOCKADDR_IN));
    	//指定远端服务器的3个参数
    	server.sin_family=AF_INET; //指定地址家族
    	server.sin_port=htons(PORT);//指定端口号
    	server.sin_addr.s_addr=inet_addr(SERVER_ADDRESS);//server.sin_addr.s_addr=htonl(SERVER_ADDRESS)
    			//sin_addr字段用于保存IP地址,sin_addr字段也是一个结构体,sin_addr.s_addr用于保存最终的IP地址
    	        //inet_addr()函数用于将形如"127.0.0.1"字符串转换为IP地址格式
    
    //4.连接到服务器
    	connect(sClient,(struct sockaddr *)&server,sizeof(SOCKADDR_IN)); 
    
    //5.建立连接后传输数据
    	char  szMessage[MSGSIZE]; //收发缓冲区
    	int ret; //成功接收到的字节数
    	while(TRUE)
    	{
    		printf("Send:");
    		//从键盘输入
    		gets(szMessage);
    		//发送数据
    		//指明发送数据的套接字,待发送数据的保存地址,指明数据长度
    		send(sClient,szMessage,strlen(szMessage),0);
    
    		//接收数据
    		ret=recv(sClient,szMessage,MSGSIZE,0);
    		szMessage[ret]='\0'; //添加这个截断字符
    
    		printf("Received [%d bytes ]: '%s'\n",ret,szMessage);
    
    	}
    //6.释放资源和结束工作
    	closesocket(sClient);
    	WSACleanup();
    	return 0;
    }
    

    ###服务端

    #include<WinSock2.h>
    #include<stdio.h>
    
    #define PORT 5150
    #define MSGSIZE 1024
    
    #pragma comment(lib,"ws2_32.lib")
    
    int main()
    {
    //1.初始化
    	WSADATA     wsaData;
    	WSAStartup(0x0202,&wsaData);
    
    //2.创建服务端+客户端套接字  地址
    	SOCKET sListen;
    	sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    	SOCKET sClient; //无需初始化
    
    //3. 服务端自身地址的设置
    	SOCKADDR_IN local;
    	SOCKADDR_IN client;  //客户端的地址 此处无需处理
    	local.sin_family=AF_INET;
    	local.sin_port=htons(PORT);
    	local.sin_addr.s_addr=htonl(INADDR_ANY);
    
    //4.定义一个客户端地址+绑定操作
    
    	bind(sListen,(struct sockaddr * ) &local ,sizeof(SOCKADDR_IN));
    
    //5.将socket设置为监听模式
    	listen(sListen,1);   //参数2表示可以监听的个数
    
    //6.接收客户端发送的连接请求
    	int iaddrSize=sizeof(SOCKADDR_IN);
    	sClient=accept(sListen,(struct sockaddr *)&client,&iaddrSize);  //注意此处最后一个参数是地址,而不是长度和bind函数不同
    
    	//打印客户端的部分信息
    	 printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
    
    //7.传输数据
    	 char szMessage[MSGSIZE];  //收发缓冲区
    	 int ret ; //收到的个数
    	 while(TRUE)
    	 {
    		 ret=recv(sClient,szMessage,MSGSIZE,0);
    		 szMessage[ret]='\0';
    		  printf("Received [%d bytes]: '%s'\n", ret, szMessage);
    		printf("Send:");
    		//从键盘输入
    		gets(szMessage);   
    		send(sClient,szMessage,strlen(szMessage),0); 
    	 }
    	 return 0;
    }
    

    #二、windows socket套接字简单封装
    参考:https://blog.csdn.net/gaoanchen/article/details/49019821
    ###客户端头文件

    #pragma once
    #include<WinSock2.h>
    #include<stdio.h>
    #pragma comment(lib,"ws2_32.lib")
    #include<assert.h>  //因为需要对很多API函数的返回值检测,使用assert断言来处理错误
    
    //宏定义
    #define TCP_DATA 1
    #define UDP_DATA 2
    
    //TCP连接限制
    #define MAX_TCP_CONNECT 10
    
    //缓冲区上限
    #define MAX_BUFFER_LEN 1024
    
    //客户端类
    class Client
    {
    public:
    	Client(); 
    	virtual ~Client();
    	void init(int inet_type,char*addr,unsigned short port);  //通信协议,地址,端口号
    	void sendData(const char * buff,const int len);
    	void getData(char* buff,const int len);
    
    	//get函数
    	char* getProto();
    	char* getIP();
    	unsigned short getPort();
    private:
    	int m_type;//通信协议类型
    	SOCKET m_socket;  //本地套接字
    	sockaddr_in serveraddr; //服务器地址结构
    };
    

    ###客户端源文件

    #include"A.h"
    Client::Client()
    {
    	WSADATA wsa;
    	int rslt=WSAStartup(0x0202,&wsa);
    	assert(rslt==0);
    };
    Client::~Client()
    {
    	if(m_socket!=INVALID_SOCKET)
    		closesocket(m_socket);
       WSACleanup(); //卸载WinSock DLL
    }
    void Client::init(int inet_type,char* addr,unsigned short port)
    {
    	int rslt;
    	m_type=inet_type;
    	if(m_type==TCP_DATA)
    		m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    	else if(m_type==UDP_DATA)
    		m_socket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    	assert(m_socket!=INVALID_SOCKET);
    	//设置服务器的地址结构体
    	serveraddr.sin_family=AF_INET;
    	serveraddr.sin_addr.S_un.S_addr=inet_addr(addr);
    	serveraddr.sin_port=htons(port);
    	memset(serveraddr.sin_zero,0,8);
    	if(m_type==TCP_DATA)
    	{
    		rslt=connect(m_socket,(sockaddr*)&serveraddr,sizeof(sockaddr)); //客户端请求
    		assert(rslt==0);
    	}
    }
    void Client::sendData(const char*buff,const int len)
    {
    	int rslt;
    	if(m_type==TCP_DATA)
    	rslt=	send(m_socket,buff,len,0);
    	else if(m_type==UDP_DATA)
    		rslt=sendto(m_socket,buff,len,0,(sockaddr*)&serveraddr,sizeof(serveraddr));
    	if(SOCKET_ERROR==rslt)
    	{
    		printf("send failed.\n");
    		closesocket(m_socket);
    		WSACleanup();
    	}
    }
    void Client::getData(char* buff,const int len)
    {
    	int rslt;
    	int addrLen=sizeof(sockaddr_in);
    	memset(buff,0,len);
    	if(m_type==TCP_DATA)
    		rslt=recv(m_socket,buff,len,0);
    	else if(m_type==UDP_DATA)
    		rslt=recvfrom(m_socket,buff,len,0,(sockaddr *)&serveraddr,&addrLen);
    	assert(rslt>0);
    }
    char* Client::getProto()
    {
    	if(m_type==TCP_DATA)
    		return "TCP";
    	else if(m_type==UDP_DATA)
    		return "UDP";
    	else 
    		return "";
    }
    char * Client::getIP()
    {
    	return inet_ntoa(serveraddr.sin_addr);
    }
    unsigned short Client::getPort()
    {
    	return ntohs(serveraddr.sin_port);
    }
    

    ###服务端头文件

    #pragma once
    //服务端因为要处理多个客户端连接请求,因此需要为每个客户端开辟新的进程
    #include<WinSock2.h>
    #include<Windows.h>
    #include<list>
    #include<stdio.h>
    #include<assert.h>
    #include<iostream>
    using namespace std;
    
    //宏定义
    #define TCP_DATA 1
    #define UDP_DATA 2
    
    //TCP连接限制
    #define MAX_TCP_CONNECT 10
    
    //缓冲区上限
    #define MAX_BUFFER_LEN 1024
    
    //服务端类
    class Server
    {
    public:
    	Server(void);
    	~Server(void);
    	void init(int inet_type,char*addr,unsigned short port);
    	void start(); //启动服务器
    	virtual void connect(sockaddr_in * client); //连接时候处理
    	virtual int procRequest(sockaddr_in * client,const char* req,int reqLen,char*resp); //处理客户端请求
    	virtual void disConnect(sockaddr_in * client);//断开时候处理
    	//get函数
    	char* getProto();
    	char* getIP(sockaddr_in * serverAddr=NULL); //获取IP
    	unsigned short getPort(sockaddr_in *serverAddr=NULL); //获取端口
    private:
    	CRITICAL_SECTION * cs; //临界区对象
    	int m_type; 
    	SOCKET m_socket;
    	sockaddr_in serverAddr; //服务端地址
    	list<sockaddr_in*> clientAddrs; //客户端地址结构列表
    	sockaddr_in* addClient(sockaddr_in client); //添加客户端地址结构
    	void delClient(sockaddr_in * client);  //删除客户端的地址结构
    	friend DWORD WINAPI threadProc(LPVOID lpParam); //线程处理函数作为友元函数
    
    };
    

    ###服务端源文件

    #include "Server.h"
    //服务器端线程处理函数结构
    struct SockParam
    {
    	SOCKET rsock; //远程的socket
    	sockaddr_in *raddr;  //远程地址结构
    	Server * pServer;  //服务器对象指针
    	 SockParam(SOCKET rs,sockaddr_in * ra,Server *ps)
    	 {
    		 rsock=rs;
    		 raddr=ra;
    		 pServer=ps;
    	 }
    };
    DWORD WINAPI threadProc(LPVOID lpParam)
    {
    	SockParam sp=*(SockParam*)lpParam;   //对传入的参数进行解析
    	Server *s=sp.pServer;
    	SOCKET sock=s->m_socket;
    	SOCKET clientSock=sp.rsock;
    	sockaddr_in *clientAddr=sp.raddr;
    
    	CRITICAL_SECTION * cs=s->cs;  //服务端类的临界区对象
    	int rslt;
    	char req[MAX_BUFFER_LEN+1]={0};//数据缓冲区,方便输出
    	do
    	{
    		rslt=recv(clientSock,req,MAX_BUFFER_LEN,0);//接收数据
    		if(rslt>0)
    			break;
    		char resp[MAX_BUFFER_LEN]={0}; //接受处理后的数据
    		EnterCriticalSection(cs);
    		rslt=s->procRequest(clientAddr,req,rslt,resp);//处理后返回数据的长度
    		LeaveCriticalSection(cs);
    		assert(rslt<=MAX_BUFFER_LEN);//不会超过MAX_BUFFER_LEN
    		rslt=send(clientSock,resp,rslt,0); //发送tcp数据
    	}
    	while(rslt!=0||rslt!=SOCKET_ERROR);
    	s->delClient(clientAddr);
    	s->disConnect(clientAddr);//断开连接后处理
    	return 0;
    }
    //线程处理函数使用传递的服务器对象指针pServer获取服务器socket,地址和临界区对象。
    //	和客户端不同的是,服务接收发送数据使用的socket不是本地的socket而是客户端的socket!
    //	为保证线程的并发控制,使用临界区的2个函数保证,中间的请求处理函数和UDP使用的相同。
    //	另外,线程的退出表示客户端的连接断开,这里更新客户端列表并调用disconnect允许服务器做最后的处理,
    //	和connect类似,这一对函数只针对tcp通信,对于UDP通信不存在调用关系。
    
    Server::Server(void)
    {
    	cs=new CRITICAL_SECTION();
    	InitializeCriticalSection(cs); //初始化临界区
    	  WSADATA wsa;
        int rslt=WSAStartup(WINSOCK_VERSION,&wsa);//加载WinSock DLL
        assert(rslt==0);
    }
    Server::~Server(void)
    {
    	 for(list<sockaddr_in*>::iterator i=clientAddrs.begin();i!=clientAddrs.end();++i)//清空客户端地址结构
        {
            delete *i;
        }
        clientAddrs.clear();
        if(m_socket!=INVALID_SOCKET)
            closesocket(m_socket);//关闭服务器socket
        WSACleanup();//卸载WinSock DLL
        DeleteCriticalSection(cs);
        delete cs;
    }
    void Server::init(int inet_type,char* addr,unsigned short port)
    {
    	int rslt;
    	m_type=inet_type;
    	if(m_type==TCP_DATA)
    		m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建TCP套接字
    	else if(m_type==UDP_DATA)
    		m_socket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    	assert(m_socket!=INVALID_SOCKET);
    	//设置服务端的地址
    	serverAddr.sin_family=AF_INET;
    	serverAddr.sin_addr.S_un.S_addr=inet_addr(addr);
    	serverAddr.sin_port=htons(port);
    	rslt=bind(m_socket,(sockaddr *)&serverAddr,sizeof(serverAddr)); //绑定地址和端口
    	assert(rslt==0);
    	if(m_type==TCP_DATA)  //如果是TCP,需要监听
    	{
    		rslt=listen(m_socket,MAX_TCP_CONNECT); //监听客户端连接
    		assert(rslt!=0);
    	}
    }
    void Server::start()
    {
    	int rslt;
    	sockaddr_in client; //客户端地址结构
    	int addrLen=sizeof(client);
    	SOCKET clientSock; //客户端socket
    	char  buff[MAX_BUFFER_LEN];  //UDP数据缓存
    	while(true)
    	{
    		if(m_type==TCP_DATA)
    		{
    			clientSock=accept(m_socket,(sockaddr*)&client,&addrLen); //接受请求
    			if(clientSock==INVALID_SOCKET)
    				break;
    			assert(clientSock!=INVALID_SOCKET);
    			sockaddr_in *pc=addClient(client); //添加一个客户端
    			connect(pc);  //连接处理函数
    			SockParam sp(clientSock,pc,this); //参数结构
    			HANDLE thread=CreateThread(NULL,0,threadProc,(LPVOID)&sp,0,NULL); //创建连接线程
    			assert(thread!=NULL);
    			CloseHandle(thread); //关闭线程
    		}
    		else if(m_type==UDP_DATA)
    		{
    			memset(buff,0,MAX_BUFFER_LEN);
    			rslt=recvfrom(m_socket,buff,MAX_BUFFER_LEN,0,(sockaddr*)&client,&addrLen);
    			assert(rslt>0);
    			char resp[MAX_BUFFER_LEN]={0}; //接收处理后的函数
    			rslt=procRequest(&client,buff,rslt,resp); //处理请求
    			rslt=sendto(m_socket,resp,rslt,0,(sockaddr*)&client,addrLen); //发送UDP数据
    		}
    	}
    }
    void Server::connect(sockaddr_in * client)
    {
    	cout<<"客户端"<<getIP(client)<<"["<<getPort(client)<<"]"<<"连接。"<<endl;
    }
    int Server::procRequest(sockaddr_in*client,const char* req,int reqLen,char*resp)
    {
        cout<<getIP(client)<<"["<<getPort(client)<<"]:"<<req<<endl;
        if(m_type==TCP_DATA)
            strcpy(resp,"TCP回复");
        else if(m_type==UDP_DATA)
            strcpy(resp,"UDP回复");
        return 10;
    }
    void Server::disConnect(sockaddr_in *client)
    {
    	    cout<<"客户端"<<getIP(client)<<"["<<getPort(client)<<"]"<<"断开。"<<endl;
    }
    char* Server::getProto()
    {
        if(m_type==TCP_DATA)
            return "TCP";
        else if(m_type==UDP_DATA)
            return "UDP";
        else
            return "";
    }
    
    char* Server::getIP(sockaddr_in*addr)
    {
        if(addr==NULL)
            addr=&serverAddr;
        return inet_ntoa(addr->sin_addr);
    }
    unsigned short Server::getPort(sockaddr_in*addr)
    {
        if(addr==NULL)
            addr=&serverAddr;
        return htons(addr->sin_port);
    }
    sockaddr_in * Server::addClient(sockaddr_in client)
    {
    	sockaddr_in *pc=new sockaddr_in(client);
    	clientAddrs.push_back(pc);
    	return pc;
    }
    void Server::delClient(sockaddr_in * client)
    {
    	assert(client!=NULL);
    	delete client;
    	clientAddrs.remove(client);
    }
    

    #三、IP地址的表示形式与各个转换函数
    计算机中不使用点分十进制保存IP地址,因为会浪费存储空间。
    使用无符号长整型数来存储和表示IP地址。
    分为网络字节序和主机字节序
    1.网络字节序
    TCP/IP规定,低位存储地址中保存数据的高位字节。这种存储顺序格式称为网络字节序。所以数据的传输顺序是由高位至低位进行的。
    为使通信双方都能够理解数据分组所携带的原地址、目的地址、分组长度等二进制数据,不同类型(比如路由器、交换机或者计算机等)和不同操作系统的设备在发送每个分组数据之前,都必须将二进制数据转换为TCP/IP标准的网络字节顺序格式。
    结构体in_addr(S_un)保存网络字节顺序格式的IP地址。
    其中有一个变量 S_addr 以u_long变量表示的主机格式IP地址。

    函数:

    unsigned long inet_addr(const char*cp)  将点分法IP地址字符串转化为in_addr结构体中的IP地址格式
    
    char *inet_ntoa(struct in_addr in) 将in_addr结构体中的IP地址转换为点分十进制格式的字符串
    

    2.主机字节序
    不同的主机在对IP地址进行存储时使用的格式也不同。
    有4个函数可以实现主机字节序与网络字节序之间的转换

    htonl() 将u_long类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
    htons() 将u_short类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
    ntohl() 将u_long类型的网络字节顺序IP地址转换为主机字节顺序格式
    ntohs() 将u_short类型的TCP网络字节顺序IP地址转换为主机字节顺序格式
    

    3.TCP流量限制措施决定recvBuf不会溢出,而UDP套接字recvBuf没有流量限制,因此发送的数据报大小一旦超出recvBuf的限制,就会被丢弃。
    4.为了数据安全,可靠,用阻塞接受,而需要轮询时则采用非阻塞操作。
    5.跨平台的基于UDP协议通信代码
    https://blog.csdn.net/wqf363/article/details/1376014
    6.C++各大库汇总
    https://blog.csdn.net/wqf363/article/details/1406251

    展开全文
  • 程序实时聊天socket

    万次阅读 热门讨论 2019-01-29 14:02:06
    项目背景:小程序直播平台上显示实时聊天 技术站:小程序API &amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;nbsp;首先对于不...
  • 程序采用WINCAP从指定网卡上获取ETH数据和发送ETH数据,实现了IP协议,ICMP协议和ARP协议。在此技术上你可以很容易的模拟实现UDP协议等简单的应用层协议,或者监控网络,编写攻击程序
  • Django微信小程序后台开发教程

    万次阅读 多人点赞 2018-10-19 20:38:05
    Django微信小程序后台开发教程1 申请小程序,创建hello world小程序2 添加交互框和按钮3 在服务器配置hello django4 实现计算器接口5 配置服务器将后端与微信小程序连接5.1 uwsgi配置5.2 http协议(80端口)下的...
  • socket获取网卡信息

    2010-11-30 19:43:54
    本人已经将程序调好 直接编译运行即可,请大家下载
  • socket编程之获取客户端和服务端ip

    万次阅读 2018-12-16 13:25:43
    getsockname函数用于获取与某个套接字关联的本地协议地址 getpeername函数用于获取与某个套接字关联的外地协议地址 定义如下: #include&lt;sys/socket.h&gt; int getsockname(int sockfd, struct ...
  • 通常我们认为 socket地址信息 和 socket句柄 是一一对应的,不能往一个socket句柄中,传入不同的地址信息。 但真是这样的吗? 咨询了一些朋友,有两种答案。特别是做服务器的朋友,说UDP可以这样,一般只建...
  • 使用C++的socket套接字编写的简单的木马程序,实现了获取屏幕截图、控制开关机、获取目录列表、获取单位时间内的键盘按键记录等简单功能 压缩包里是客户端和服务器端的源代码;可以根据自己的实际需要调整IP和监听...
  • 概述: ...然后,举了一个使用TCP协议的客户端和服务器端例子来展示Socket类和ServerSocket类的用法。同样,我们举了一个使用UDP协议的客户端和服务器端例子来展示DatagramSocket类的用法。对于每个类对
  • C# 实现socket通讯程序(客户端)

    千次阅读 2019-06-20 17:00:30
    要实现客户端与服务器的聊天小程序,其实在客户端就只做三件事,连接、发送、接收,下面是最简单例子的部分代码。其他编程语言实现网络编程也基本是一样的。然后写完客户端,就要写服务端的程序了,下一篇博客出门左...
  • SOCKET 编程 获取本机IP 地址

    千次阅读 2012-07-15 11:55:19
    程序: #include #include #include #include #include #include #include #include #include #include #define PORT 7778 #define MAXDATASIZE 1024 int main() { struct sockaddr_in user_addr,my...
  • java网络编程----------获取Socket信息

    千次阅读 2017-06-09 23:43:07
    Socket信息获取
  • socket多人聊天程序C语言版(二)

    万次阅读 多人点赞 2016-10-15 22:38:35
    不过相对于1V1的程序,我经过大改,采用链表来动态管理。这样效率真的提升不少,至少CPU使用率稳稳的在20以下,不会飙到100了。用C语言写这个还是挺费时间的,因为什么功能函数都要自己写,不像C++有STL库可以用,...
  • 网络编程socket深入探索中,前期已经了解过基础的网络编程,但太过浅显,只知道基础的几次握手和数据传输而已,但其中的明细和规则不是特别了解,故进一步探索,继续记录归档。
  • 包含Server.cpp和Client.cpp,简单的使用套接字实现Client获取本机计算机名和ip地址发送到Server
  • 微信小程序——判断socket是否已关闭
  • https://blog.csdn.net/zhengfl/article/details/21977831
  • Socket原理讲解

    万次阅读 多人点赞 2019-07-18 15:50:36
    对TCP/IP、UDP、Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。那么我想问: 1.什么是TCP/IP、UDP? 2.Socket在哪里呢? 3.Socket是什么呢? 4.你会使用它们吗?什么是TCP/IP、UDP...
  • 关于TCP IP网络通讯的资料非常...可以看到数据包包含了源端口号和目的端口号,客户端socket向服务端发起连接时,系统会给socket随机分配一个源端口号,我们可以通过getsocketname来获取连接成功的socket的原端口信息。
  • 客户端通常可以使用Socket的构造器来连接到指定服务器,其实客户端程序也非常简单,它仅仅使用Socket建立与指导IP地址、指定端口的连接,并使用Socket获取输入流读取数据。该客户端程序是一个Android应用,因此还是...
  • 在 python 使用socket 获取 IP

    千次阅读 2015-07-23 17:00:26
    使用socket获取更多的信息 getsocketname:获得本机的信息(IP和port) getpeername:获得远程机器的信息(IP和port) fileno:每一个socket对应一个fd,使用此方法可以获得fd,为一个整数 import socket s = socket....
  • vc 通过网络获取时间(使用socket

    热门讨论 2011-06-29 15:10:26
    vc编写的用来通过网络获取时间的程序,使用socket api
  • Socket编程之ping程序的实现

    千次阅读 多人点赞 2016-01-06 19:28:51
    ping程序的实现,网络协议分析,TCP/IP协议详解的课程设计,Socket网络编程
  • Python使用Socket写一个聊天程序

    千次阅读 2018-03-25 22:52:10
    方法:客户端1:获取发送信息的地址和端口,然后发送给对方的服务端2,服务端2监听所有地址来的固定端口的消息,然后将消息打印出来 然后回复一条给客户端1说收到了。客户端1可以继续向服务端2发送消息。 客户端...
  • Android Socket通信详解及聊天程序示例

    万次阅读 多人点赞 2017-04-06 09:02:34
    getInputStream():返回该Socket对象对应的输入流,让程序通过该输入流从Socket里面获取数据 getOutputStream():返回该Socket对象对应的输出流,让程序通过该输出流向Socket写入数据 下面看一个...
  • Socket获取客户端IP地址及端口号

    千次阅读 2011-01-28 14:07:00
    Socket获取客户端IP地址及端口号 程序设计>>>.Net>>> Socket获取客户端IP地址及端口号 >>> 正文 Socket获取客户端IP地址及端口号 Socket类包含一些非常...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 214,766
精华内容 85,906
关键字:

获取程序的socket地址