• Winsock版本的“hello world!”


    1.基于TCP协议的“hello world!”

    1)服务器端:WSAStartup()->socket()->bind()->listen()->accept()->send()/recv()->closesocket()->WSACleanup().

     1 #include <WinSock2.h>
     2 #pragma comment (lib,"ws2_32")
     3 
     4 int main()
     5 {
     6     WSADATA wsaData;
     7     WSAStartup(MAKEWORD(2,2),&wsaData);
     8 
     9     SOCKET s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    10 
    11     sockaddr_in sockaddr;
    12     sockaddr.sin_family=PF_INET;
    13     sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    14     sockaddr.sin_port=htons(827);
    15 
    16     bind(s,(SOCKADDR*)&sockaddr,sizeof(SOCKADDR));
    17 
    18     listen(s,1);
    19 
    20     SOCKADDR clientAddr;
    21     int nSize=sizeof(SOCKADDR);
    22     SOCKET clientSock;
    23     clientSock=accept(s,(SOCKADDR*)&clientAddr,&nSize);
    24 
    25     send(clientSock,"hello client 
    ",strlen("hello client 
    ")+sizeof(char),NULL);
    26 
    27     closesocket(clientSock);
    28     closesocket(s);
    29 
    30     WSACleanup();
    31     return 0;
    32 }
    View Code

    2)客户端:WSAStartup()->socket()->connect()->recv()/send()->closesocket()->WSACleanup().

     1 #include <stdio.h>
     2 #include <WinSock2.h>
     3 #pragma comment (lib,"ws2_32")
     4 
     5 int main()
     6 {
     7     WSADATA wsaData;
     8     WSAStartup(MAKEWORD(2,2),&wsaData);
     9 
    10     SOCKET s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    11 
    12     sockaddr_in sockAddr;
    13     sockAddr.sin_family=PF_INET;
    14     sockAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    15     sockAddr.sin_port=htons(827);
    16 
    17     connect(s,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR));
    18 
    19     char szBuffer[MAXBYTE]={0};
    20 
    21     recv(s,szBuffer,MAXBYTE,NULL);
    22 
    23     printf("szBuffer=%s 
    ",szBuffer);
    24 
    25     closesocket(s);
    26 
    27     WSACleanup();
    28     return 0;
    29 }
    View Code

    2.基于UDP协议的“hello world!”

    1)服务器端:

     1 #include <WinSock2.h>
     2 #include <stdio.h>
     3 #pragma comment (lib,"ws2_32")
     4 
     5 int main()
     6 {
     7     WSADATA wsaData;
     8     WSAStartup(MAKEWORD(2,2),&wsaData);
     9 
    10     SOCKET s=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
    11 
    12     sockaddr_in sockAddr;
    13     sockAddr.sin_family=PF_INET;
    14     sockAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    15     sockAddr.sin_port=htons(827);
    16 
    17     bind(s,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR));
    18 
    19     sockaddr_in clientAddr;
    20     int len=sizeof(sockaddr_in);
    21     char buf[MAXBYTE]={0};
    22     recvfrom(s,buf,MAXBYTE,0,(SOCKADDR*)&clientAddr,&len);
    23     printf("%s 
    ",buf);
    24 
    25     sendto(s,"hello world client",strlen("hello world client")+sizeof(char),0,(SOCKADDR*)&clientAddr,sizeof(SOCKADDR));
    26 
    27     closesocket(s);
    28 
    29     WSACleanup();
    30     return 0;
    31 }
    View Code

    2)客户端:

     1 #include <Winsock2.h>
     2 #include <stdio.h>
     3 #pragma comment (lib,"ws2_32")
     4 
     5 int main()
     6 {
     7     WSADATA wsaData;
     8     WSAStartup(MAKEWORD(2,2),&wsaData);
     9 
    10     SOCKET s=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
    11 
    12     sockaddr_in sockAddr;
    13     sockAddr.sin_family=PF_INET;
    14     sockAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    15     sockAddr.sin_port=htons(827);
    16 
    17     sendto(s,"hello world server",strlen("hello world server")+sizeof(char),0,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR));
    18     sockaddr_in clientAddr;
    19     int len=sizeof(sockaddr_in);
    20     char buf[MAXBYTE]={0};
    21     recvfrom(s,buf,MAXBYTE,0,(SOCKADDR*)&clientAddr,&len);
    22     printf("%s 
    ",buf);
    23 
    24     closesocket(s);
    25 
    26     WSACleanup();
    27     return 0;
    28 }
    View Code

    3.Winsock的相关函数:

    1)初始化ws2_32.dll的函数:int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);

    参数说明:1> wVersionRequested:Windows Sockets API提供的调用方可使用的最高版本号。

         2> lpWSAData:指向WSADATA结构的指针,用来接收Windows Sockets实现的细节。

    2)释放ws2_32.dll的函数:int WSACleanup(void);

    3)创建套接字:SOCKET socket(int af,int type,int protocol);

    参数说明:1> af:指定应用程序使用的通信协议簇,对于TCP/IP协议簇,该参数始终为PF_INET。

         2> type:指定套接字的类型,流套接字为SOCK_STREAM,为TCP协议使用;数据包套接字为SOCK_DGRAM,为UDP协议使用。

         3> protocol:指定应用程序所使用的通信协议。TCP:IPPROTO_TCP; UDP:IPPROTO_UDP。

    4)关闭套接字:int closesocket(SOCKET s);

    参数说明:s:套接字描述符。

    5)绑定IP地址和端口号:int bind(SOCKET s,const struct sockaddr FAR *name,int namelen);

    参数说明:1> s;指定待绑定的Socket描述符。

           2> name:指定一个sockaddr结构:

    1 struct sockaddr{ 
    2    u_short sa_family;
    3    char sa_data[14];
    4 };
    View Code

    实际使用过程中,结构体是sockaddr_in:

    1  struct sockaddr_in{
    2     short     sin_family;
    3     u_short sin_port;
    4     struct    in_addr sin_addr;
    5     char      sin_zero[8];
    6 };
    View Code

    成员变量sin_family设置为PF_INET;sin_port设置为端口号;sin_addr结构体中只包含一个公用体:

    1 struct in_addr{
    2   union{
    3             struct { u_char   s_b1, s_b2, s_b3, s_b4;}   S_un_b;
    4             struct { u_short  s_w1, s_w2; }                   S_un_w;
    5             u_long                                                          S_addr;
    6    }S_un;
    7 };
    View Code

    该成员变量为一个整数,一般用函数inet_addr()把字符串形式的IP地址转换为unsigned long整型的整数值。

          3> namelen:指定name缓冲区的长度。

    6)监听端口:int listen(SOCKET s,int backlog);

    参数说明:1> s:使套接字s处于监听状态。

           2> backlog:为s维护一个客户连接请求队列。

    7)接受请求:SOCKET accept(SOCKET s,struct sockaddr FAR *addr,int FAR *addrlen);

    参数说明:1> s:指定处于监听状态的套接字。

         2> addr:用来返回新创建的套接字的地址。

           3> addrlen:addr的长度。

    8)连接:int connect(SOCKET s,const struct sockaddr FAR *name,int namelen);

    参数说明:1> s:客户端创建的套接字。

           2> name:该结构中包含了服务器端中的IP地址和端口号。

           3> namelen:指定name缓冲区的长度。

    9)基于TCP的发送函数:int send(SOCKET s,const char FAR *buf,int len,int flags);

    参数说明:1> s:指定发送端套接字描述符。

         2> buf:指明一个存放应用程序要发送数据的缓冲区。

         3> len:指明实际要发送的数据的字节数。

           4> flags:一般设置为0。

    10)基于TCP的接收函数:int recv(SOCKET s,char FAR *buf,int len,int flags);

    参数说明:1> s:指定接收端套接字描述符。

         2> buf:指定一个存放接收到的数据的缓冲区。

         3> len:指定缓冲区长度。

           4> flags:一般设置为0。

    11)基于UDP的发送函数:int sendto(SOCKET s,const char FAR *buf,int len,int flags,const struct sockaddr FAR *to,int tolen);

    12)基于UDP的接收函数:int sendto(SOCKET s,char FAR *buf,int len,int flags,struct sockaddr FAR *from,int FAR *fromlen);

    13)数据存储的字节顺序:本地字节顺序根据CPU架构的不同可能是小尾方式,也可能是大尾方式,如在x86CPU架构上使用小尾顺序,即高位存放高字节,低位存放低字节。而网络字节顺序一定是大尾方式。

    本地字节顺序转换为网络字节顺序的函数:u_short htons(u_short hostshort);     u_long htonl(u_long hostlong);

    网络字节顺序转换为本地字节顺序的函数:u_short ntohs(u_short netshort);     u_long ntohl(u_long netlong);

            

  • 相关阅读:
    ETCD 添加节点报错 tocommit(2314438) is out of range [lastIndex(0)]. Was the raft log corrupted, truncated, or lost?
    如何删除docker镜像中已配置的volume
    kubeadm初始化集群
    kubeadm安装依赖镜像
    standard_init_linux.go:178: exec user process caused "no such file or directory"
    kubernetes支持local volume
    git http方式时保存密码
    分布式核心技术
    docker使用
    Python实用日期时间处理方法汇总
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4180575.html
Copyright © 2020-2023  润新知