zoukankan      html  css  js  c++  java
  • 基于TCP套接字实现的简单Demo

    由于代码的注释已经很详尽了,所以这里不再作过多说明.仅仅贴出代码和结果图.


    值得注意的是必须先启动server程序再启动client.


    Server:

     1 #include <WINSOCK2.H>    //套接字库
     2 #include <stdio.h>
     3 
     4 #define PORT       6000 //服务器端口
     5 #define MSGSIZE    1024 //收发缓冲区的大小
     6 
     7 #pragma comment(lib, "ws2_32.lib") //链接静态库
     8 
     9 DWORD WINAPI FunThread(LPVOID); //创建一个线程,专门用来接收数据
    10 
    11 SOCKET      sClient; //连接所用套节字
    12 SOCKET      sListen; //监听套接字
    13 SOCKADDR_IN client; //保存客户的地址信息
    14 int         iaddrSize = sizeof(SOCKADDR_IN);
    15  
    16 int main()
    17 {
    18 
    19     WSADATA     wsaData;        //WSADATA结构体中主要包含了系统所支持的Winsock版本信息
    20     SOCKADDR_IN local;        //定义本地套接字地址
    21     char        s_Message[MSGSIZE]; //收发缓冲区
    22 
    23     WSAStartup(0x0202, &wsaData); //初始化套接字库
    24     
    25     sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建服务器监听套节字。TCP协议
    26     
    27     local.sin_family = AF_INET; //AF_INET指明使用TCP/IP协议族
    28     local.sin_port = htons(PORT);//指明连接服务器的端口号
    29     local.sin_addr.s_addr = htonl(INADDR_ANY);//自动获取本机地址
    30 
    31     bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));//地址绑定到套接字
    32     
    33     listen(sListen, 1);//开始监听
    34     
    35     sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);//建立连接,返回用于连接的套接字
    36     printf("Accepte client:%s:%d
    ", inet_ntoa(client.sin_addr), ntohs(client.sin_port));//输出客户端的IP地址和端口
    37 
    38 
    39     HANDLE hThread=CreateThread(NULL,0,FunThread,0,0,0);//运行至此创建专门的接收线程用于接收客户端发送
    40                                 //的数据,在监听主线程上创建一个新的数据接收线程
    41     CloseHandle(hThread);//关闭线程句柄
    42 
    43 
    44     //用于从服务器端向客户端发送数据
    45     while (TRUE)
    46     {
    47         printf("Server Send:");
    48         //从键盘输入
    49         gets(s_Message);                        
    50         //发送数据
    51         send(sClient, s_Message, strlen(s_Message), 0); 
    52     }
    53     return 0; 
    54 } 
    55 
    56 
    57 //当接收数据时调用此线程函数
    58 DWORD WINAPI FunThread(LPVOID)
    59 {   
    60     char c_Message[MSGSIZE]; //接收数据缓冲区
    61     int ret; //接收字节的个数
    62     while (TRUE)
    63     {  
    64         ret = recv(sClient, c_Message, MSGSIZE, 0);//接收数据到缓冲区
    65         
    66         //判断是否成功接收,如果未成功接收则重启监听,将原缓冲区的数据归零
    67         if(ret==SOCKET_ERROR)
    68         {
    69             printf("
    client is closed!");
    70             
    71             sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);//重新开始监听
    72             printf("
    Accepte new client:%s:%d", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
    73             memset(c_Message,0,1024);//将原来的client message归零
    74             continue;
    75         }
    76         c_Message[ret] = '';
    77         printf("
    Received: %s
    ", c_Message); 
    78     }
    79     return 0; 
    80 }<strong>
    81 </strong>


    Client:

     1 #include <WINSOCK2.H> //套接字库
     2 #include <stdio.h>
     3 
     4 #define SERVER_ADDRESS "127.0.0.1" //服务器端IP地址,由于服务也在本地机器上所以用环回地址127.0.0.1
     5 
     6 #define PORT           6000    //客户端绑定端口     
     7 #define MSGSIZE        1024        //客户端接收数据缓冲区大小    
     8 #pragma comment(lib, "ws2_32.lib") 
     9 
    10 DWORD WINAPI FunThread(LPVOID); //对于客户端接收数据的线程函数   
    11 
    12 SOCKET      sClient;         //客户端套接字      
    13 SOCKADDR_IN server;           //服务器端套接字
    14 
    15      
    16 int main()
    17 { 
    18     WSADATA     wsaData; 
    19     char        c_Message[MSGSIZE]; //数据缓冲区
    20     
    21     WSAStartup(0x0202, &wsaData); //初始化套接字库
    22     
    23     sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    //创建客户端套接字
    24     
    25     memset(&server, 0, sizeof(SOCKADDR_IN));               //先将保存地址的server置为全0
    26     server.sin_family = PF_INET;                           //声明地址格式是TCP/IP地址格式
    27     server.sin_port = htons(PORT);                         //指明连接服务器的端口号
    28     server.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);    //指明连接服务器的IP地址
    29     
    30 
    31     connect(sClient, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)); //连到刚才指明的服务器上
    32 
    33     HANDLE hThread=CreateThread(NULL,0,FunThread,0,0,0);;//客户端开辟接收数据线程
    34     CloseHandle(hThread);
    35 
    36     //客户端向服务器发送数据
    37     while (TRUE)
    38     {
    39         printf("Client Send:");
    40         gets(c_Message);   
    41         
    42         send(sClient, c_Message, strlen(c_Message), 0); 
    43         if(!strcmp(c_Message,"exit"))//client自身退出
    44             exit(1);
    45     }
    46     
    47     // 释放连接和进行结束工作
    48     closesocket(sClient);
    49     WSACleanup();
    50     return 0;
    51 }
    52 
    53 //接收线程函数
    54 DWORD WINAPI FunThread(LPVOID)
    55 {
    56     char   s_Message[MSGSIZE];//定义接收缓冲区
    57     int    ret; 
    58     while (TRUE)
    59     {
    60         ret = recv(sClient, s_Message, MSGSIZE, 0);//接收服务器端的数据
    61     
    62 
    63         //判断是否接收
    64         if(ret==SOCKET_ERROR)
    65         {
    66             printf("
    Server is closed!
    ");
    67             exit(1);
    68         }
    69         s_Message[ret] = '';  
    70         //显示接收数据
    71         printf("
    Received: %s
    ", s_Message);
    72         
    73         //如果服务器端发送exit则client退出
    74         if(!strcmp(s_Message,"exit"))//server让client退出
    75             exit(1);
    76     }
    77     return 0;
    78 }<strong>
    79 </strong>


    运行结果如下:




  • 相关阅读:
    域渗透:ptk(pass the key)
    QQ拼音输入法6.0 DLL劫持实现提权
    进程关系
    进程控制
    进程环境
    系统数据文件和信息
    文件和目录
    标准I/O
    文件描述符标志/文件表项
    SSL安全原理
  • 原文地址:https://www.cnblogs.com/vpoet/p/4659744.html
Copyright © 2011-2022 走看看