Socket网络通信

用Socket实现聊天系统,前提加入加入静态库:

#pragma comment(lib,"ws2_32.lib")

1.加载套接字库,确定socket的版本;
WSAStartup():初始化sock套接字

2.创建套接字,用于监听;
socket(AF_INET,SOCK_DGRAM,0);
1)AF_INET=PF_INET;地址族
2)参数意思:Internet协议,socket类型
3)流式套接字(SOCK_STREAM):用到的协议TCP
4)数据报套接字(SOCK_DGRAM): 无连接的、不可靠的UDP
5)与地址族相关的协议:为0

3.绑定套接字;

4.将套接字设为监听模式:listen()
1)套接字描述符
2)等待链接队列的最大长度

5.接收客户端链接请求:accept();
1)参数信息:
2)sockSrv:已经设置为监听状态的套接字

6.打印接收到的数据;
printf();

7.发送数据
1)TCP协议: send() recv()
2)UDP协议: sendto() recvfrom()

8.关闭套接字库;
1) closesocket(sockClient);
2) WSACleanup();

客户端实现:

#include 
#include 
#include 
#include 
using namespace std;

#pragma comment(lib,"ws2_32.lib")

int main()
{
    printf("请输入对方IP地址\n");
    char szDestIP[16];//192.168.100.100
    scanf("%s",szDestIP);

    //加载套接字库,确定socket的版本;
    //typedef unsigned short  WORD;
    //typedef WSAData  WSADATA;

    WORD wVersionRequested;
    wVersionRequested=MAKEWORD(2,2);
    WSADATA wsaData; //实际加载的套接字版本保存在wsData  

    //WSAStartup():初始化sock套接字
    int nErr=WSAStartup(wVersionRequested,&wsaData);
    if(nErr!=0)
   {
       printf("加载套接字库失败\n");
       return 0;
   }

   //LOBYTE是一个宏 ,低位字节||高位字节
   //wsaData.wVersion:实际加载的版本号
   if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)
   {
       printf("加载套接字库不一致\n");
       WSACleanup();  
       return 0;
   }

   //创建套接字,用于监听;
   SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
   SOCKADDR_IN addrSrv;
   addrSrv.sin_addr.S_un.S_addr=inet_addr(szDestIP);             
   addrSrv.sin_family=AF_INET;  //使用INET协议
   addrSrv.sin_port=htons(9880);//指定端口号

   char szRecvBuf[200];
   char szSendBuf[200];

   int nlength=sizeof(SOCKADDR);

   while(TRUE)
   {
       //输入消息
       printf("请输入待发送消息:\n");
       scanf("%s",szSendBuf);

       //发送消息
       //TCP协议: send()    recv()
       //UDP协议: sendto()   recvfrom()
       sendto(sockClient,szSendBuf,strlen(szSendBuf)+1,0,(SOCKADDR*)&addrSrv,nlength);
       //等待接收数据
       recvfrom(sockClient,szRecvBuf,200,0,(SOCKADDR*)&addrSrv,&nlength );  //接收数据,会阻塞   

       if('q'==szRecvBuf[0])
       {
           sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,nlength);     
           printf("聊天结束\n");
           break;
       }

       //打印接收到的数据
       printf("%s 说:%s\n",inet_ntoa(addrSrv.sin_addr),szRecvBuf);
   }

   //关闭套接字库
   closesocket(sockClient);
   WSACleanup();

    system("pause");
    return 0;
}

服务端实现:

#include 
#include 
#include 
#include 
#include 
using namespace std;

#pragma comment(lib,"ws2_32.lib")


int main()
{
    //加载套接字库,确定socket的版本;
    //typedef unsigned short    WORD;
    //typedef WSAData  WSADATA;

    WORD wVersionRequested;
    wVersionRequested=MAKEWORD(2,2);

    WSADATA wsaData; //实际加载的套接字版本保存在wsData  

    //WSAStartup:初始化sock套接字
    int nErr=WSAStartup(wVersionRequested,&wsaData);
    if(nErr!=0)
   {
       printf("加载套接字库失败\n");
       return 0;
   }

   //LOBYTE是一个宏 ,低位字节||高位字节
   //wsaData.wVersion:实际加载的版本号
   if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)
   {
       printf("加载套接字库不一致\n");
       WSACleanup();   //
       return 0;
   }

   //创建套接字,用于监听;
   //AF_INET=PF_INET;地址族
   //参数意思:Internet协议,socket类型
   //流式套接字(SOCK_STREAM):用到的协议TCP
   //数据报套接字(SOCK_DGRAM):  无连接的、不可靠的UDP
   //与地址族相关的协议:为0
   SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
   SOCKADDR_IN addrSrv;
   addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
    //htonl()将主机顺序转换为网络字节顺序

   addrSrv.sin_family=AF_INET;    //使用INET协议
   addrSrv.sin_port=htons(9880);//指定端口号

   char szRecvBuf[200];
   char szSendBuf[200];

   //绑定套接字
   //sockSrv :要绑定的套接字;
   //addrSrv:套接字的本地地址信息;
   //sizeof(SOCKADDR):地址结构体的大小;
    if(SOCKET_ERROR==bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
    {
        printf("绑定套接字失败\n");
        return 0;
    }

    SOCKADDR_IN addrClient;
    int nlength=sizeof(SOCKADDR);

   while(TRUE)
   {
       recvfrom(sockSrv,szRecvBuf,200,0,(SOCKADDR*)&addrClient,&nlength );  //接收数据,会阻塞   
       if('q'==szRecvBuf[0])
       {
            sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,nlength);  
            printf("聊天结束\n");
            break;
       }

       //打印接收到的数据
       printf("%s 说 %s\n",inet_ntoa(addrClient.sin_addr),szRecvBuf);

       //发送数据
       printf("请输入待发送信息:\n");
       scanf("%s",szSendBuf);
       sendto(sockSrv,szSendBuf,strlen(szSendBuf)+1,0,(SOCKADDR*)&addrClient,nlength);  //发送数据 
   }

   //关闭套接字库
   closesocket(sockSrv);
   WSACleanup();

    system("pause");
    return 0;
}

改成发布型(release)的;

发布结果:
客户端:
Socket网络通信_第1张图片

服务端:
这里写图片描述

你可能感兴趣的:(Socket网络通信)