• linux下TCP通信的例子


    服务器:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <unistd.h>
    #include <netdb.h>
    #include "DieWithMessage.h"
    
    #define BUFSIZE 512
    
    static const int MAXPENDING = 5;
    
    int SetupTCPServerSocket(const char *service);
    int AcceptTCPConnection(int servSock);
    void HandleTCPClient(int clntSocket);
    void PrintSocketAddress(const struct sockaddr *address, FILE *stream);
    
    int main(int argc, char *argv[])
    {
        if(argc != 2 )
            DieWithUserMessage("Parameter(s)", "<Server Port/Service");
    
        char *service = argv[1];
    
        int servSock = SetupTCPServerSocket(service);
    
        if(servSock < 0)
            DieWithUserMessage("SetupTCPServerSocket() failed", service);
    
        for(;;)
        {
            int clntSock = AcceptTCPConnection(servSock);
    
            HandleTCPClient(clntSock);
            close(clntSock);
        }
    }
    
    
    int SetupTCPServerSocket(const char *service)
    {
        struct addrinfo addrCriteria;
        memset(&addrCriteria, 0, sizeof(addrCriteria));
    
        addrCriteria.ai_family = AF_UNSPEC;
        addrCriteria.ai_flags = AI_PASSIVE;
        addrCriteria.ai_socktype = SOCK_STREAM;
        addrCriteria.ai_protocol = IPPROTO_TCP;
    
        struct addrinfo *servAddr;
        int rtnVal = getaddrinfo(NULL, service, &addrCriteria, &servAddr);
        if(rtnVal != 0)
            DieWithUserMessage("getaddrinfo() failed", gai_strerror(rtnVal));
    
        int servSock = -1;
        struct addrinfo *addr;
        for(addr=servAddr; addr != NULL; addr=addr->ai_next)
        {
            servSock = socket(servAddr->ai_family, servAddr->ai_socktype, servAddr->ai_protocol);
            if(servSock<0)
                continue;
    
            if((bind(servSock, servAddr->ai_addr, servAddr->ai_addrlen) == 0) && 
                    (listen(servSock, MAXPENDING) == 0))
            {
                struct sockaddr_storage localAddr;
                socklen_t addrSize = sizeof(localAddr);
                if(getsockname(servSock, (struct sockaddr *)&localAddr, &addrSize) < 0)
                    DieWithSystemMessage("getsockname() failed");
    
                fputs("Binding to ", stdout);
                PrintSocketAddress((struct sockaddr *)&localAddr, stdout);
                fputc('\n', stdout);
                break;
            }
            
            close(servSock);
            servSock = -1;
    
        }
    
        freeaddrinfo(servAddr);
    
        return servSock;
    }
    
    int AcceptTCPConnection(int servSock)
    {
        struct sockaddr_storage clntAddr;
        socklen_t clntAddrLen = sizeof(clntAddr);
    
        int clntSock = accept(servSock, (struct sockaddr*)&clntAddr, &clntAddrLen);
        if(clntSock < 0)
            DieWithSystemMessage("accept() fail");
    
        fputs("Handling client ", stdout);
        PrintSocketAddress((struct sockaddr *) &clntAddr, stdout);
        fputc('\n', stdout);
    
        return clntSock;
    }
    
    void HandleTCPClient(int clntSocket)
    {
        char buffer[BUFSIZE];
        ssize_t numBytesRcvd = recv(clntSocket, buffer, BUFSIZE, 0);
    
        if(numBytesRcvd < 0)
            DieWithSystemMessage("recv() failed");
    
        while(numBytesRcvd > 0)
        {
            ssize_t numBytesSent = send(clntSocket, buffer, numBytesRcvd, 0);
            if(numBytesSent < 0)
                DieWithSystemMessage("send() failed");
            else if(numBytesSent != numBytesRcvd)
                DieWithUserMessage("send()", "send unexpected number of bytes");
    
            numBytesRcvd = recv(clntSocket, buffer, BUFSIZE, 0);
            if(numBytesRcvd < 0)
                DieWithSystemMessage("recv() failed");
        }
    
        close(clntSocket);
    }
    
    
    void PrintSocketAddress(const struct sockaddr *address, FILE *stream)
    {
        if(address == NULL || stream == NULL)
            return;
    
        void *numericAddress;
        char addrBuffer[INET6_ADDRSTRLEN];
        in_port_t port;
    
        switch(address->sa_family)
        {
            case AF_INET:
                numericAddress = &((struct sockaddr_in *)address)->sin_addr;
                port = ntohs(((struct sockaddr_in *)address)->sin_port);
                break;
            case AF_INET6:
                numericAddress = &((struct sockaddr_in6 *)address)->sin6_addr;
                port = ntohs(((struct sockaddr_in6 *)address)->sin6_port);
                break;
            default:
                fputs("[unknown type]", stream);
                return;
        }
    
        if(inet_ntop(address->sa_family, numericAddress, addrBuffer, sizeof(addrBuffer)) == NULL)
            fputs("[invalid address]", stream);
        else
        {
            fprintf(stream, "%s", addrBuffer);
            if(port != 0)
                fprintf(stream, "-%u", port);
        }
    }

    客户端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include "DieWithMessage.h"
    #include "TCPClientUtility.c"
    
    #define BUFSIZE 512
    
    int main(int argc, char *argv[])
    {
        if(argc < 3 || argc > 4)
        {
            DieWithUserMessage("Parameter(s)", "<Server Address/Name> <Echo Word> [<Server Port/Service]");
        }
    
        char *server = argv[1];
        char *echoString = argv[2];
    
        char *service = (argc==4)? argv[3] : "echo";
    
        int sock = SetupTCPClientSocket(server, service);
        if(sock < 0)
            DieWithUserMessage("SetupTCPClientSocket() failed", "unable to connect");
    
        size_t echoStringLen = strlen(echoString);
    
        ssize_t numBytes = send(sock, echoString, echoStringLen, 0);
    
        if(numBytes < 0)
            DieWithSystemMessage("send() failed");
        else if (numBytes != echoStringLen)
            DieWithUserMessage("send()", "sent unexpected number of bytes");
    
        unsigned int totalBytesRevd = 0;
        fputs("Received: ", stdout);
    
        while(totalBytesRevd < echoStringLen)
        {
            char buffer[BUFSIZE];
            numBytes = recv(sock, buffer, BUFSIZE - 1, 0);
    
            if(numBytes < 0)
                DieWithSystemMessage("recv() failed");
            else if(numBytes == 0)
                DieWithUserMessage("recv()", "connection closed prematurely");
    
            totalBytesRevd += numBytes;
            buffer[numBytes] = '\0';
            fputs(buffer, stdout);
        }
    
        fputc('\n', stdout);
    
        close(sock);
        exit(0); 
    }

    另外两个文件:

    TCPClientUtility.c

    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include "DieWithMessage.h"
    
    
    int SetupTCPClientSocket(const char *host, const char *service)
    {
        struct addrinfo addrCriteria;
        memset(&addrCriteria, 0, sizeof(addrCriteria));
    
        addrCriteria.ai_family = AF_UNSPEC;
        addrCriteria.ai_socktype = SOCK_STREAM;
        addrCriteria.ai_protocol = IPPROTO_TCP;
    
        struct addrinfo *servAddr;
    
        int rtnVal = getaddrinfo(host, service, &addrCriteria, &servAddr);
        if(rtnVal != 0)
            DieWithUserMessage("get addrinfo() failed", gai_strerror(rtnVal));
    
        int sock = -1;
        struct addrinfo *addr;
        for(addr = servAddr; addr != NULL; addr = addr->ai_next)
        {
            sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
            if(sock <0)
                continue;
    
            if(connect(sock, addr->ai_addr, addr->ai_addrlen)==0)
                break;
    
            close(sock);
            sock = -1;
        }
    
        freeaddrinfo(servAddr);
        return sock;
    }

    DieWithMessage.h

    #ifndef DIE_WITH_MESSAGE
    #define DIE_WITH_MESSAGE
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void DieWithUserMessage(const char* msg, const char *detail)
    {
        fputs(msg, stderr);
        fputs(": ", stderr);
        fputs(detail, stderr);
        fputc('\n', stderr);
        exit(1);
    }
    
    void DieWithSystemMessage(const char *msg)
    {
        perror(msg);
        exit(1);
    }
    
    #endif
  • 相关阅读:
    让UILabel的文字顶部对齐
    常用的iOS开发或者优化的小工具
    AppStoreID--安装URL--应用更新URL--应用评分URL
    iOS 下载功能:断点下载(暂停和开始)(NSURLConnectionDataDelegate方法)
    iOS QLPreviewController(Quick Look)快速浏览jpg,PDF,world等
    如何不让UITableView滚动
    解析字典包含关键字比如ID,description等,MJExtension 框架 不能直接设置变量与其同名。
    今天犯了个小错误:_dataArray.count>1 和_dataArray.count>0搞混淆了
    获取当前的日期和时间-数码
    C/C++中的段错误(Segmentation fault)[转]
  • 原文地址:https://www.cnblogs.com/wouldguan/p/2770773.html
Copyright © 2020-2023  润新知