zoukankan      html  css  js  c++  java
  • 【实验 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);
    }
    }

  • 相关阅读:
    《大话数据结构》第1章 数据结构绪论 1.2 你数据结构怎么学的?
    伍迷七八月新浪微博集锦
    《大话数据结构》第9章 排序 9.7 堆排序(下)
    《大话数据结构》第3章 线性表 3.8.2 单链表的删除
    《大话数据结构》第9章 排序 9.5 直接插入排序
    《大话数据结构》第9章 排序 9.8 归并排序(上)
    《大话数据结构》第2章 算法基础 2.9 算法的时间复杂度
    《大话数据结构》第1章 数据结构绪论 1.1 开场白
    《大话数据结构》第9章 排序 9.1 开场白
    [AWS] Assign a public IP address to an EC2 instance after launched
  • 原文地址:https://www.cnblogs.com/chengJAVA/p/3342951.html
Copyright © 2011-2022 走看看