• 【实验 1-1】编写一个简单的 TCP 服务器和 TCP 客户端程序。程序均为控制台程序窗口。


    在新建的 C++源文件中编写如下代码。

    1.TCP 服务器端
    #include<winsock2.h> //包含头文件
    #include<stdio.h>
    #include<windows.h>
    #pragma comment(lib,"WS2_32.lib") //显示连接套接字库
    int main() //主函数开始
    {
    WSADATA data; //定义 WSADATA 结构体对象,WSADATA结构被用来储存调用AfxSocketInit全局函数返回  Windows Sockets初始化信息。这个结构被用来存储被                                    //WSAStartup函数调用后返回的Windows Sockets数据。它包含Winsock.dll执行的数据。

    WORD w=MAKEWORD(2,0); //定义版本号码,WORD是微软SDK中的类型,WORD的意思为字,是2byte的无符号整数,表示范围0~65535.
    char sztext[]="欢迎你 "; //定义并初始化发送到客户端的字符数组
    ::WSAStartup(w,&data); //初始化套接字库,本函数必须是应用程序或DLL调用的第一个Windows Sockets函数.它允许应用程序或DLL指明Windows Sockets API的版本号及                                    //获得特定Windows Sockets实现的细节.应用程序或DLL只能在一次成功的WSAStartup()调用之后才能调用进一步的Windows Sockets API函数.

    SOCKET s,s1; //定义连接套接字和数据收发套接字句柄
    s=::socket(AF_INET,SOCK_STREAM,0); //创建 TCP 套接字,socket()向应用程序提供创建套接字的手段,DOS、WINDOWS中仅支持AF_INET,它是网际网区域。TCP流式                                                            //套接字(SOCK_STREAM)提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复地发送,且按发送顺序接收.如果调用                                                          //者不希望特别指定使用的协议,则置为0,使用默认的连接模式。
    sockaddr_in addr,addr2; //定义套接字地址结构
    int n=sizeof(addr2); //获取套接字地址结构变量大小
    addr.sin_family=AF_INET; //初始化地址结构
    addr.sin_port=htons(75);//将主机的无符号短整形数转换成网络字节顺序,sin_port:指Socket对应的端口号。

    addr.sin_addr.S_un.S_addr=INADDR_ANY;//addr.sin_addr.S_un.S_addr是SOCKET编程中的一个结构体,用来指定IP地址的。INADDR_ANY就是指定地址为                                                                        //0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。
    ::bind(s,(sockaddr*)&addr,sizeof(addr)); //绑定套接字。

    /*int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR * name, int namelen);
    参数s是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。参数name 是赋给套接字s的本地地址(名字),其长度可变,结构随通信域的不同而不同。namelen表明了name的长度.如果没有错误发生,bind()返回0。否则返回SOCKET_ERROR。*/


    ::listen(s,2); //监听套接字

    /*int PASCAL FAR listen(SOCKET s, int backlog);
    参数s标识一个本地已建立、尚未连接的套接字号,服务器愿意从它上面接收请求。backlog表示请求连接队列的最大长度,用于限制排队请求的个数,目前允许的最大值为5。如果没有错误发生,listen()返回0。否则它返回SOCKET_ERROR。*/


    printf("服务器已经启动 "); //输出提示信息
    while(true)
    {
    s1=::accept(s,(sockaddr*)&addr2,&n); //接受连接请求

    /*SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen);
    参数s为本地套接字描述符,在用做accept()调用的参数前应该先调用过listen()。addr 指向客户方套接字地址结构的指针,用来接收连接实体的地址。addr的确切格式由套接字创建时建立的地址族决定。addrlen 为客户方套接字地址的长度(字节数)。如果没有错误发生,accept()返回一个SOCKET类型的值,表示接收到的套接字的描述符。否则返回值INVALID_SOCKET。*/


    if(s1!=NULL)
    {
    printf("%s 已经连接上 ",inet_ntoa(addr2.sin_addr));

    /*char FAR * inet_ntoa( struct in_addr in);将一个IP转换成一个互联网标准点分格式的字符串。*/
    ::send(s1,sztext,sizeof(sztext),0); //向客户端发送字符数组

    /*int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags);
    参数s为已连接的本地套接字描述符。buf 指向存有发送数据的缓冲区的指针,其长度由len 指定。flags 指定传输控制方式,如是否发送带外数据等。如果没有错误发生,send()返回总共发送的字节数。否则它返回SOCKET_ERROR。*/


    }
    ::closesocket(s); //关闭套接字句柄
    ::closesocket(s1);
    ::WSACleanup(); //释放套接字库
    if(getchar()) //如果有输入则关闭程序
    {
    return 0; //正常结束程序
    }
    else
    {::Sleep(100);
    }
    }}
    2. TCP 客户端

    #include<winsock2.h> //包含头文件
    #include<stdio.h>
    #include<windows.h>
    #pragma comment(lib,"WS2_32.lib") //显式连接套接字库
    int main() //主函数开始
    {
    WSADATA data; //定义 WSADATA 结构体对象
    WORD w=MAKEWORD(2,0); //定义版本号码
    ::WSAStartup(w,&data); //初始化套接字库
    SOCKET s; //定义连接套接字和数据收发套接字句柄
    char sztext[10]={0};
    s=::socket(AF_INET,SOCK_STREAM,0); //创建 TCP 套接字
    sockaddr_in addr;//定义套接字地址结构
    addr.sin_family=AF_INET; //初始化地址结构
    addr.sin_port=htons(75);
    addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

    /*127.0.0.1是回送地址,指本地机,一般用来测试使用。回送地址(127.x.x.x)是本机回送地址(Loopback Address),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,协议软件立即返回,不进行任何网络传输。*/
    printf("客户端已经启动 ");//输出提示信息
    ::connect(s,(sockaddr*)&addr,sizeof(addr));

    /*int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR * name, int namelen);
    参数s是欲建立连接的本地套接字描述符。参数name指出说明对方套接字地址结构的指针。对方套接字地址长度由namelen说明。*/


    ::recv(s,sztext,sizeof(sztext),0);

    /*int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags);
    参数s 为已连接的套接字描述符。buf指向接收输入数据缓冲区指针,其长度由len 指定。flags 指定传输控制方式,如是否接收带外数据等。如果没有错误发生,recv()返回总共接收的字节数。如果连接被关闭,返回0。否则它返回SOCKET_ERROR。*/  

    printf("%s ",sztext);
    ::closesocket(s); //关闭套接字句柄
    ::WSACleanup(); //释放套接字库
    if(getchar()) //如果有输入则关闭程序
    {
    return 0; //正常结束程序
    }
    else
    {::Sleep(100);
    }
    }

  • 相关阅读:
    CF-807B
    CF-807A
    sort()的升降序函数操作
    CF-805D
    CF-805B
    CF-805A
    CF-796C
    CF-796B
    图论学习四之Disjoint set union并查集
    图论学习三之Shortest Path最短路
  • 原文地址:https://www.cnblogs.com/chengJAVA/p/3342951.html
Copyright © 2020-2023  润新知