• C Socket初探


    前段时间写了个C# Socket初探,这次再写个C语言的Socket博文,运行效果如下:

    实现步骤:

    1. Server端

    #include <stdio.h>                   //用于printf等函数的调用
    #include <winsock2.h>                //Socket的函数调用 
    #pragma comment (lib, "ws2_32")      //C语言引用其他类库时,除了.h文件外,还要加入对应的lib文件(这个不同于C#)
    int main()
    {
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData);
    
        SOCKET s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    
        sockaddr_in sockaddr;
        sockaddr.sin_family=PF_INET;
        sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");   //需要绑定到本地的哪个IP地址
        sockaddr.sin_port=htons(9000);                          //需要监听的端口
        bind(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));        //进行绑定动作
    
        listen(s, 1);                                           //启动监听
    
        printf("listening on port [%d].
    ", 9000);
    
        while(TRUE)
        {
            SOCKADDR clientAddr;
            int size=sizeof(SOCKADDR);
    
            SOCKET clientsocket;
            clientsocket=accept(s, &clientAddr, &size);               //阻塞,直到有新tcp客户端连接
            printf("***SYS***    New client touched.
    ");
    
            char* msg="Hello, my client.
    ";
            send(clientsocket, msg, strlen(msg)+sizeof(char), NULL);  //这里的第三个参数要注意,是加了一个char长度的
            printf("***SYS***    HELLO.
    ");
    
            while(TRUE)
            {
                char buffer[MAXBYTE]={0};
                recv(clientsocket, buffer, MAXBYTE, NULL);            //一直接收客户端socket的send操作
                printf("***Client***    %s
    ", buffer);
            }
    
            closesocket(clientsocket);                                //关闭socket
        }
    
        closesocket(s);                           //关闭监听socket
        
        WSACleanup();                                                //卸载
    
        getchar();                                                   
    
        exit(0);
    }

    由于还在学习中,因此没有实现多线程,因此客户端实际上只能1个,其他的会被挡在外面

    关于socket的缓冲区还有点学问,比如最后要 结尾等,都是有原因的,建议看看资料。

    2. Client端

    #include <stdio.h>                      //用于输入、输出函数的调用,printf, gets
    #include <winsock2.h>                   //socket头文件
    #include <Windows.h>                    //为了方便调试,所以加入了等待2秒才进行连接server,这里用到了sleep函数
    
    #pragma comment (lib, "ws2_32")         //socket库文件
    int main()
    {
        Sleep(2000);                        //沉睡2秒再连接server
    
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData);
    
        SOCKET s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    
        sockaddr_in sockaddr;
        sockaddr.sin_family=PF_INET;
        sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
        sockaddr.sin_port=htons(9000);
    
        connect(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));
    
        char buffer[MAXBYTE]={0};
        recv(s, buffer, MAXBYTE, NULL);
        printf("***SERVER***%s", buffer);
    
        while(TRUE)
        {
            char* mymsg=new char[100000];
            printf("You can chat with server now:
    ");
            gets(mymsg);
            send(s, mymsg, strlen(mymsg)+sizeof(char), NULL);
    /*
    recv函数中的bufferlength参数是可以固定值的
    send函数中的bufferlength参数不能固定值,需要看实际长度,并且考虑到''字符串
    */ } closesocket(s); WSACleanup(); getchar(); exit(
    0); }

     我们来看看C写的程序,release后,这2个exe文件的大小吧:

    果然NB。

  • 相关阅读:
    kindle--瓦尔登湖
    8051
    c++
    Linux安装目录的选择
    Redis键值数据类型之散列类型
    Redis键值数据类型之字符串
    redis基本使用
    Ubuntu18.04 Redis安装
    Java String和int转换
    mysql获得自增主码的值
  • 原文地址:https://www.cnblogs.com/aarond/p/CSocket.html
Copyright © 2020-2023  润新知