zoukankan      html  css  js  c++  java
  • 简单的控制台聊天程序(C Socket编程)

    首先看一下程序代码:


    /* server.c */
    #include <stdio.h>
    #include <winsock2.h>             /* for socket */
    #include <time.h>                     /* for clock(); */

    #define LISTEN_PORT 5500    /* listening port */

    #pragma comment(lib, "ws2_32.lib")     /* import library for socket */


    int main()
    {
       HOSTENT *host_entry;
       char   host_name[256];
       int       n;
       struct WSAData wsadata;
       int     sock, length;
       struct sockaddr_in srvaddr;
       struct sockaddr     tcpaddr;
       int       msgsock;
       char    buf[1024];
       int     rval, len;
       char   c;
       char    data[1024];
       int       i;

       clock_t t_start = clock();

       if ( WSAStartup(0x0101, &wsadata) == 0)   /* Initialize */
       {
            n = gethostname(host_name, 256);                         /* get localhost name */
           host_entry = gethostbyname(host_name);              /* get localhost address */
           if ( host_entry != NULL )    /* print localhost address */
           {
               printf("%d.%d.%d.%d\n",
                   host_entry->h_addr_list[0][0]&0x00ff,
                   host_entry->h_addr_list[0][1]&0x00ff,
                   host_entry->h_addr_list[0][2]&0x00ff,
                   host_entry->h_addr_list[0][3]&0x00ff);
              
            }
            printf("Establish connecting & listening....\n");
            sock = socket(AF_INET, SOCK_STREAM, 0);   /* create socket */
            if (sock < 0 )
            {
                printf("open socket error\n");
                exit(1);
            }

            memset(&srvaddr, 0, sizeof(struct sockaddr) );
            srvaddr.sin_family = AF_INET;
            srvaddr.sin_port = htons(LISTEN_PORT);
            if ( bind(sock, (struct sockaddr*)&srvaddr, sizeof(srvaddr)) < 0 )        /* bind address */
            {
                printf("socket bind error.\n");
                exit(1);
            }

            length = sizeof(srvaddr);
            if ( getsockname(sock, (struct sockaddr*)&srvaddr, &length ) < 0 )
            {
                printf("get sock name error.\n");
                exit(1);
            }

            printf("listening port: #%d\n", ntohs(srvaddr.sin_port));

            listen(sock, 5);      /* listening */
            len = sizeof(struct sockaddr);
           
            do {
                msgsock = accept(sock, (struct sockaddr*)&tcpaddr, (int*)&len);     /* create accept sock */
                if ( msgsock == -1 )
                {
                    printf("error accept.\n");
                }
                else
                do {
                        if ( clock() - t_start > 20000 )
                        {
                            closesocket(msgsock);
                            WSACleanup();
                            printf("time out.\n");
                            exit(0);
                        }
                        memset(buf, 0, sizeof(buf));
                        if (( rval = recv(msgsock, buf, 1024, 0)) < 0 )        /* receive msg */
                        {
                            printf("recv sock msg error.\n");
                        }
                        if ( rval == 0 )
                        {
                            printf("ending connecting.\n");
                            closesocket(msgsock);
                            WSACleanup();
                            exit(1);
                        }
                        else
                        {
                            t_start = clock();
                            printf("--->%s\n", buf);
                        }
                        memset(data, 0, 1024);
                        i = 0;
                        c = getchar();
                        while ( c != 10 )
                        {
                            data[i++] = c;
                            c = getchar();
                        }
                        data[i] = '\0';
                        send(msgsock, data, sizeof(data), 0);    /* send msg */
                        t_start = clock();
                        if ( strcmp(buf, "bye") == 0 )   /* if send "bye" then end session */
                        {
                            closesocket(msgsock);
                            WSACleanup();
                            exit(1);
                        }
                       
                       
                    } while(rval != 0);
                closesocket(msgsock);
            } while(1);
        }
        WSACleanup();
       
        return 0;
    }

    /* client.c */

    #include <stdio.h>
    #include <WinSock2.h>

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

    int main(int argc, char* argv[])
    {
        HOSTENT *host_entry;
        char    host_name[256];
        int        n;
        struct WSAData wsadata;
        int     sock;
        struct sockaddr_in srvaddr;
        struct hostent *hp;
        char    data[1024];
        char    c;
        int     i = 0;
       

        if ( argc < 3 )
        {
            printf("Usage : %s ip port\n", argv[0]);
            exit(1);
        }
       

        if ( WSAStartup(0x0101, &wsadata) == 0)
        {
            n = gethostname(host_name, 256);
            host_entry = gethostbyname(host_name);
            if ( host_entry != NULL )
            {
                printf("%d.%d.%d.%d\n",
                    host_entry->h_addr_list[0][0]&0x00ff,
                    host_entry->h_addr_list[0][1]&0x00ff,
                    host_entry->h_addr_list[0][2]&0x00ff,
                    host_entry->h_addr_list[0][3]&0x00ff);
               
            }   

            sock = socket(AF_INET, SOCK_STREAM, 0);
            if ( sock < 0 )
            {
                printf("socket create error.\n");
                exit(1);
            }
            srvaddr.sin_family = AF_INET;
            hp = gethostbyname(argv[1]);
            if ( hp == 0 )
            {
                printf("unknow host : %s\n", argv[1]);
                exit(1);
            }
            memcpy((char*)&srvaddr.sin_addr, (char*)hp->h_addr, hp->h_length);
            srvaddr.sin_port = htons((unsigned short)atoi(argv[2]));
           
            if ( connect(sock, (struct sockaddr*)&srvaddr, sizeof(srvaddr)) < 0 )        /* connect server */
            {
                printf("connect server error.\n");
                exit(1);
            }
           
            while ( 1 )
            {
                memset(data, 0, 1024);
                i = 0;
                c = getchar();
                while ( c != 10 )
                {
                    data[i++] = c;
                    c = getchar();
                }
                data[i] = '\0';
                if ( send(sock, data, sizeof(data), 0) < 0 )           /* send msg to server */
                {
                    printf("send data error.\n");
                    exit(1);
                }

                if (recv(sock, data, 1024, 0) )        /* receive msg from server */
                {
                    printf("----->%s\n", data);
                }
                if ( strcmp(data, "bye") == 0 )
                {
                    closesocket(sock);
                    printf("connecting close.\n");
                    WSACleanup();
                    exit(0);
                }
            }
        }

        WSACleanup();
        return 0;
    }
       上面的程序在VC++6.0下编译通过。启动命令行,首先启动服务器server.exe,在端口5500监听,客户端以 client.exe ip 5500 (ip为服务器的ip地址)启动后,可以向服务器端发信息,然后服务器端收到信息后显示出来,并且向客户端回送信息,服务器端也可以自己发送信息,客户端 收到后也回送信息。上面的程序很简单,只是一个演示的程序,客户端首先发信息,然后服务器端发,然后客户端发.....,它们都不能连续发信息。当服务器 端连续20秒没有发信息或收到信息,会自动断开socket连接。有兴趣的朋友可以将它完善一下,让双方都可以自由的发送信息和接收信息。

  • 相关阅读:
    PHP数组函数(5)
    python3-开发面试题(python)6.24基础篇(3)
    python3开发进阶-Django框架的ORM常用字段和参数
    python3-开发面试题(python)6.23基础篇(2)
    python3 中 and 和 or 运算规律
    python3开发进阶-Django框架中的ORM的常用操作的补充(F查询和Q查询,事务)
    python3-开发面试题(python)6.22基础篇(1)
    python3开发进阶-Django框架中的ORM的常用(增,删,改,查)操作
    python3-os模块中的os.walk(目录树生成器)
    python3开发进阶-Django框架的详解
  • 原文地址:https://www.cnblogs.com/zzxap/p/2175804.html
Copyright © 2011-2022 走看看