zoukankan      html  css  js  c++  java
  • 【网络编程02】简单聊天程序

      有了上次socket的基础知识,网络编程01  可以写一个简单的聊天程序,随便复习一下基础知识。

    1.线程

      我们要实现可以同时发送和接收信息,就需要多线程了,一个用于发,一个用于收。

      这次用CreateThread来创建线程。函数原型

      HANDLE WINAPI CreateThread
      (   _In_opt_             LPSECURITY_ATTRIBUTES          lpThreadAttributes,
        _In_                    SIZE_T                      dwStackSize,
        _In_               LPTHREAD_START_ROUTINE          lpStartAddress,
        _In_opt_       LPVOID                            lpParameter,
        _In_          DWORD                               dwCreationFlags,
        _Out_opt_    LPDWORD                       lpThreadId
      );
      函数看着复杂其实用起来很简单。只需要关心传入什么函数,函数参数是什么。
      1.第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认设置
      2.第二个参数表示线程栈空间大小。传入0表示使用默认大小
      3.第三个参数表示新线程所执行的线程函数地址(函数的名字),多个线程可以使用同一个函数地址
      4.第四个参数是传给线程函数的参数。
      5.第五个参数指定什么时候调用线程,为0表示线程创建之后立即就可以进行调用。
      6.第六个参数返回线程的ID号,传入NULL表示不需要返回该线程ID号
    2.服务器端代码
      我们把发送信息和接收信息的功能封装成两个函数作为线程使用。
      
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<WinSock2.h>
     4 #pragma comment (lib,"ws2_32.lib")
     5 SOCKET newSocket;//全局变量,用来通信的套接字
     6 
     7 void recvFun();//接收信息线程
     8 void sendFun();//发送信息线程
     9 void createConnect();//创建通信套接字
    10 
    11 int main()
    12 {
    13     HANDLE h1, h2;//线程句柄
    14     createConnect();
    15     printf("连接成功...
    ");
    16     //创建线程后立即运行
    17     h1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sendFun, NULL, 0, NULL);
    18     h2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvFun, NULL, 0, NULL);
    19     WaitForSingleObject(h1, INFINITE);//会阻塞,直到线程结束
    20     WaitForSingleObject(h2, INFINITE);//会阻塞,直到线程结束
    21     closesocket(newSocket);//关闭套接字
    22     return 0;
    23 }
    24 void sendFun()
    25 {    
    26     char buf[128];
    27     while (1)
    28     {    
    29         printf("你要发送的信息:");
    30         scanf("%s", buf);
    31         send(newSocket, buf, strlen(buf) + 1, 0);//发送信息
    32     }
    33 }
    34 
    35 void recvFun()
    36 {
    37     char buf[128];
    38     while (1)
    39     {
    40         recv(newSocket, buf, 128, 0);//接收信息
    41         printf("%32s%s
    ","接收到的信息: ", buf);
    42     }
    43     
    44 }
    45 
    46 void createConnect()
    47 {
    48     SOCKET serverSocket;//监视的套接字
    49     //SOCKET newSocket;//用来通信的套接字
    50     SOCKADDR_IN newAddr;//保存客户端的socket地址信息
    51     SOCKADDR_IN addr;//地址结构体,包括ip port(端口)
    52     WSADATA data;
    53     WORD version;//socket版本
    54     int info;
    55                  /*
    56                  在使用socket之前要进行版本的设定和初始化
    57                  看不懂不用管
    58                  */
    59     version = MAKEWORD(2, 2);//设定版本
    60     info = WSAStartup(version, &data);
    61     /*应用程序或DLL只能在一次成功的WSAStartup()调用之后
    62     才能调用进一步的Windows Sockets API函数。
    63     根据版本初始化 windows socket,返回0表示成功
    64     */
    65     if (info != 0)
    66     {
    67         printf("初始化失败
    ");
    68         return;
    69     }
    70     if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2)
    71     {
    72         printf("加载失败
    ");
    73         WSACleanup();
    74         return;
    75     }
    76     //创建套接字,使用TCP协议
    77     serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    78     addr.sin_addr.S_un.S_addr = htonl(ADDR_ANY);//表示任何的ip过来连接都接受
    79     addr.sin_family = AF_INET;//使用ipv4的地址
    80     addr.sin_port = htons(6666);//设定应用占用的端口
    81     bind(serverSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR));//将套接字与端口6666,接收的ip绑定
    82     listen(serverSocket, 3);//开始监听,是否有客服端请求连接,最大连接数为3
    83     printf("开始监听,等待连接..........
    ");
    84     int len = sizeof(SOCKADDR);
    85     newSocket = accept(serverSocket, (SOCKADDR*)&newAddr, &len);
    86 }

    3.客户端代码

      客户端和服务器端代码差不多,也是两个线程用于接收和发送信息。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<WinSock2.h>
     4 #pragma comment(lib,"ws2_32.lib")
     5 SOCKET clientSocket;//全局变量,用于通信的socket
     6 void createConnect();//创建套接字
     7 void sendFun();//发送信息线程
     8 void recvFun();//接收信息线程
     9 int main()
    10 {
    11     HANDLE h1, h2;//线程句柄,其实就是一串数字用来标识线程对象
    12     createConnect();//创建套接字
    13     //创建线程后立即执行
    14     h1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sendFun, NULL, 0, NULL);
    15     h2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvFun, NULL, 0, NULL);
    16     WaitForSingleObject(h1, INFINITE);//会阻塞,直到线程运行结束
    17     WaitForSingleObject(h2, INFINITE);
    18     closesocket(clientSocket);//关闭套接字
    19     return 0;
    20 }
    21 void createConnect()
    22 {
    23     SOCKADDR_IN addr;
    24     int info;
    25     WSADATA data;
    26     WORD version;
    27     //设定版本,与初始化
    28     version = MAKEWORD(2, 2);
    29     info = WSAStartup(version, &data);
    30     if (info != 0)
    31     {
    32         printf("初始化失败
    ");
    33         return;
    34     }
    35     if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2)
    36     {
    37         printf("加载失败
    ");
    38         WSACleanup();
    39         return;
    40     }
    41     clientSocket = socket(AF_INET, SOCK_STREAM, 0);//创建套接字
    42                                                    //要连接的服务器的ip,因为现在服务器端就是本机,所以写本机ip
    43                                                    //127.0.0.1一个特殊的IP地址,表示是本机的IP地址
    44     addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    45     //端口要与服务器相同,不然找不到
    46     addr.sin_port = htons(6666);
    47     //用IPV4地址
    48     addr.sin_family = AF_INET;
    49     //主动连接服务器
    50     connect(clientSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR));
    51 }
    52 
    53 void sendFun()
    54 {    
    55     char buf[128]="你是谁";
    56     while (1)
    57     {    
    58         printf("你要发送的信息: ");
    59         scanf("%s", buf);
    60         //发送数据
    61         send(clientSocket, buf, strlen(buf) + 1, 0);
    62     }    
    63 }
    64 
    65 
    66 void recvFun()
    67 {    
    68     char buf[128];
    69     //接收服务发送的数据
    70     while (1)
    71     {
    72         recv(clientSocket, buf, 128, 0);//接收数据
    73         printf("%32s%s
    ","接收的信息为: ", buf);
    74     }
    75 }

    运行结果,可以实现聊天的功能,虽然界面不行。

     学了socket编程还可以实现木马之类的东西。原理很简单,让目标用户在后台悄悄运行你的程序,在另一端你可以发送各种命令操作程序从而实现操作用户的电脑,窃取信息。比如你发送个强制关机的命令的 str="shutdown -s -f",而目标用户的程序接收到了这个命令并且调用了 system(str)。目标用户的电脑马上就会关机。

  • 相关阅读:
    【转载】著名黑客雷蒙评价几种编程语言
    【GUI开发】Swing的一本极好的入门教材
    【数据结构】数组操作(HighArrayApp.java)
    数据另存为CSV档案(也是一种excel档案)【2】------自主选择路径
    TIniFile实现打开窗体后还原用户之前的配置的功能
    sql server内连接(inner join)、外连接(left outer join、right outer join、full outer join)、记录合并(union、union all)
    @指针、Cardinal()、Integer()、指针取值解析
    关于php编程的一些小技巧
    数据库操作,同时更新多条数据
    省份,城市,地区------三级联动菜单//要加注释
  • 原文地址:https://www.cnblogs.com/duichoumian/p/12767329.html
Copyright © 2011-2022 走看看