簡單的控制台聊天程式(C Socket編程)

來源:互聯網
上載者:User
首先看一下程式碼:

/* 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串連。有興趣的朋友可以將它完善一下,讓雙方都可以自由的發送資訊和接收資訊。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.