Socket

来源:互联网 发布:北欧移民知乎 编辑:程序博客网 时间:2024/05/22 02:25

先举个例子来说明下套接字


地区a的区号为123,b地区的区号为321,a地区的电话号码66219677要给b地区的电话号码55768444打电话。

对应为

Ip为192.168.1.1 端口号为2000的进程 要和Ip为 192.168.1.2 端口号为3000的进程通信。

不知道这样比喻行不?


一般啊,同一个IP下的进程端口号不会重复的,就如你的电话号码一样。


socket (套接字),用于描述IP地址和端口,是一个通信链的句柄,当然描述还有协议,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。


我们打电话之前,双方必须各自拥有一台电话机,同样,进行socket通信,双方需要有各自的socket,socket实质上提供了进程通信的端点。


socket通信示意图:



代码片段

服务器端:

#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32.LIB")
#define Port 3000
#define MaxSize 1024

void main()
{
   //加载套接字
    WORDwVersionRequested;
    WSADATAwsaData;
    int err;

   wVersionRequested=MAKEWORD(2,2);

    err =WSAStartup(wVersionRequested,&wsaData);
    if(err!=0)
    {
       printf("WinSock DLL版本有问题");
       return;
    }

    if(LOBYTE(wsaData.wVersion)!=2||
   HIBYTE(wsaData.wVersion)!=2)
    {
        WSACleanup();
        return;
    }

    //创建监听的套接字
    SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

    SOCKADDR_IN addrSrv;

     //把U_LONG的主机字节顺序转换为TCP/IP网络字节顺序
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY)

    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(Port);

    //绑定套接字
    bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
    //将套接字设置为监听模式,准备接受用户请求
     listen(sockSrv,5);

     SOCKADDR_INaddrClient;
    int len=sizeof(SOCKADDR);

    printf("%sn","Welcome,the Host is running!nWating for someone comesin!");
    while (1)
    {
         //等待用户请求到来
         SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
          charsendBuf[MaxSize];
         sprintf(sendBuf,"Welcome to the Host,%s.",inet_ntoa(addrClient.sin_addr));
         //发送数据
         send(sockConn,sendBuf,MaxSize,0);
          //接收数据
          charrevBuf[MaxSize];
         char name[20] = {0};
         int flag = 1;
         while(recv(sockConn,revBuf,MaxSize,0) != -1)
         {
                //打印接受数据
              if(flag == 1)
              {
                   strcpy(name, revBuf);
                   printf("%s comes in!n",name);
                   flag = 2;
               }
               else
               {
                    printf("%s:%sn",name, revBuf);
               }
           }
          //关闭套接字
          closesocket(sockConn);
     }
}


客户端:

#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32.LIB")
#define Port 3000
#define MaxSize 1024

void main()
{
    WORDwVersionRequested;
    WSADATAwsaData;
    int err;

   wVersionRequested=MAKEWORD(2,2);

   err=WSAStartup(wVersionRequested,&wsaData);
    if(err!=0)
    {
       printf("WinSock DLL版本有问题");
       return;
    }

    if(LOBYTE(wsaData.wVersion)!=2||
   HIBYTE(wsaData.wVersion)!=2)
   {
      WSACleanup();
      return;
    }

   //创建套接字
    SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);

   SOCKADDR_IN addrSrv;
   addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//把U_LONG的主机字节顺序转换为TCP/IP网络字节顺序

   //127.0.0.1 回路地址
   addrSrv.sin_family=AF_INET;
   addrSrv.sin_port=htons(Port);

   //向服务器发送请求
   if(connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))== -1)
    {
       printf("连接失败!输入回车结束程序!n");
       getchar();
       return;
    }

   //接受数据
    charrecBuf[MaxSize];
   recv(sockClient,recBuf,MaxSize,0);
   printf("%sn",recBuf);

   //输入name
   printf("Input your Name:n");
    charname[20] = {0};
   gets(name);

   //发送数据
   send(sockClient,name,strlen(name)+1,0);
   while(1)
    {
       gets(recBuf);
       send(sockClient,recBuf,strlen(recBuf)+1,0);
    }
   //关闭套接字
   closesocket(sockClient);
   getchar();
   WSACleanup();
}