Windows实现基于TCP的网络应用程序

21 篇文章 0 订阅
4 篇文章 0 订阅

客户端流程如下:

(1)创建套接字(socket)

(2)向服务器发送请求(connect)

(3)和服务器进行通信(send/recv)

(4)关闭套接字

#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib") 
int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD(1,1);
    
    err = WSAStartup(wVersionRequested,&wsaData);

    if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion) != 1)
    {
        WSACleanup();
        return 0;
    }
    //创建套接字
    SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);

    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    //向服务器发出连接请求
    connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//第一个参数是即将在其上建立连接的套接字,第二个参数设定连接服务器端地址信息,第三个信息指定服务器端地址长度

    //接收数据
    char recvBuff[100];
    recv(sockClient,recvBuff,100,0);//第一个参数表示已建立连接的套接字,第二个参数指向缓冲区的指针,保存接收的信息,第三个参数表示缓冲区的大小,第四个参数一般设为0
    printf("%s\n",recvBuff);
    //向服务器发送信息
    send(sockClient,"This is lisi",strlen("This is lisi")+1,0);//第一个参数表示已建立连接的套接字,第二个参数指向一个缓冲区,包含将要传的信息,第三个参数是缓冲区的长度,第四个参数一般设为0
    //关闭套接字
    closesocket(sockClient);
    WSACleanup();
    return 0;
}

服务器端流程如下:

(1)创建套接字(socket)

(2)绑定套接字到一个本地地址和端口上(bind)

(3)将套接字设为接听模式,准备接收客户请求(listen)

(4)等待用户请求,接收请求时,返回一个对应于此次连接的套接字(accept)

(5)用返回的套接字和客户端进行通信(sned/recv)

(6)返回,等待另一客户请求

(7)关闭套接字

#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib") 
int main()
{
    WORD wVersionRequested;
    WSADATA    wsaData;
    int err;

    wVersionRequested = MAKEWORD(1,1);//MAKEWORD宏可以获得WSAStartup的高位和低位

    err = WSAStartup(wVersionRequested,&wsaData);//WSAStartup用来加载套接字,wVersionRequested用来指定准备加载的Winsock库的版本,高位指副版本,地位指主版本

    if(err!=0)
    {
        return 0;
    }

    if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion) != 1)
    {
        WSACleanup();
        return 0;
    }
    //创建用于接听的套接字
    SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);//第一个参数指定地址族,对于TCP/IP协议,只能是AF_INET(PF_INET),第二个参数指定Socket类型,SOCK_STREAM产生流式套接字,SOCK_DGRAM产生数据报套接字

    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//sin_addr指定套接字主机的IP,htonl把一个u_long类型的值从主机字节顺序转换为TCP/IP网络字节顺序
    addrSrv.sin_family = AF_INET;//sin_family表示地址族,对于IP地址,将一直是AF_INET
    addrSrv.sin_port = htons(6000);//sin_port指定的是将要分配给套接字的端口,htons函数把一个u_short类型的值从主机字节顺序转换为TCP/IP网络字节顺序

    //绑定套接字
    bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//第一个参数指定要绑定的套接字,第二个参数指定了套接字的本地地址信息,第三个参数指定第二个参数的长度
    //将套接字设为接听模式,准备接收客户请求
    listen(sockSrv,5);//第一个参数是套接字描述符,第二个参数是等待队列的最大长度。
    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);
    while(1)
    {
        //等待客户请求到来
        SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len);//第一个参数是套接字描述符,该套接字已通过listen将其设置为接听状态。第二个参数是指向一个缓冲区的指针,该缓冲区用来接收连接实体的地址
        //也就是当客户端向服务器发起连接,服务器端接收这个连接时,保存发起连接这个客户端的IP地址信息和端口信息,第三个参数返回一个指向整形的指针,返回包含地址信息的长度
        char sendBuff[100];
        sprintf(sendBuff,"Welcome %s to http://www.sunxin.org",inet_ntoa(addrClient.sin_addr));
        printf("%s\n",sendBuff);
        //发送数据
        send(sockConn,sendBuff,strlen(sendBuff)+1,0);//第一个参数表示已建立连接的套接字,第二个参数指向一个缓冲区,包含将要传的信息,第三个参数是缓冲区的长度,第四个参数一般设为0
        char recvBuff[100];
        //接收数据
        recv(sockConn,recvBuff,100,0);//第一个参数表示已建立连接的套接字,第二个参数指向缓冲区的指针,保存接收的信息,第三个参数表示缓冲区的大小,第四个参数一般设为0
        //打印接收的数据
        printf("%s\n",recvBuff);
        //关闭套接字
        closesocket(sockConn);
    }
    return 0;
}
客服端界面:

服务器端界面:


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值