欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

linux & windows tcp客户端和服务端,发送和接收文件(公网测试通过)

程序员文章站 2022-03-04 08:49:38
...

tcp服务端: 

如果客户端发送download命令,则给该客户端发送文件

#ifdef WIN32
#include <winsock2.h>
#include <WS2tcpip.h>
#include <Windows.h>
#elif 1
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>

#define _PORT_ 9999
#define SERVER_IP "127.0.0.1"
#define _BACKLOG_ 10

int is_begin_with(const char * str1,char *str2)
{
    if(str1 == NULL || str2 == NULL)
        return -1;
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    if((len1 < len2) || (len1 == 0 || len2 == 0))
        return -1;
    char *p = str2;
    int i = 0;
    while(*p != '\0')
    {
        if(*p != str1[i])
            return 0;
        p++;
        i++;
    }
    return 1;
}

int main()
{
#ifdef WIN32
    WORD sockVersion = MAKEWORD(2, 2);
    WSADATA wsaData;
    if (WSAStartup(sockVersion, &wsaData) != 0)
    {
        return 0;
    }
#elif 1
#define INVALID_SOCKET ~0
#endif

    int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET)
    {
        printf("socket error !");
        return 0;
    }
    struct sockaddr_in server_socket;
    struct sockaddr_in client_socket;
    memset(&server_socket, 0, sizeof(server_socket));
    server_socket.sin_family = AF_INET;
    server_socket.sin_port = htons(_PORT_);
    server_socket.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(sock, (struct sockaddr *)&server_socket, sizeof(struct sockaddr_in)) < 0)
    {
        printf("bind error,error code is %d,error string is :%s\n",errno,strerror(errno));
        close(sock);
        return 1;
    }
    if(listen(sock,_BACKLOG_) < 0)
    {
        printf("listen error,error code is %d,error string is %s\n",errno,strerror(errno));
        close(sock);
        return 2;
    }
    printf("bind and listen success,wait accept...\n");

    for(;;)
    {
        socklen_t len = sizeof(struct sockaddr);
        int client_sock = accept(sock, (struct sockaddr *)&client_socket, &len);
        if(client_sock == INVALID_SOCKET)
        {
            printf("accept error, error is %d,errstring is %s\n",errno,strerror(errno));
            close(sock);
            return 3;
        }
        char buf_ip[INET_ADDRSTRLEN];
        memset(buf_ip,'\0',sizeof(buf_ip));
        inet_ntop(AF_INET,&client_socket.sin_addr,buf_ip,sizeof(buf_ip));
        printf("get connect,ip is %s,port is %d\n",buf_ip,ntohs(client_socket.sin_port));
        char buf[1024];
        memset(buf,'\0',sizeof(buf));//跟前面的初始化对比
        read(client_sock, buf, sizeof(buf));
        //printf("client :# %s\n",buf);
        if(is_begin_with(buf, "download") != 1) {
            //printf("command unvalid!");
            continue;
        }
        FILE *fp;
        fp = fopen("./maroon.rcc" , "r");
        //fseek( fp , 0 , SEEK_SET);
        char buffer[4096];
        int totalbytes = 0;
        while(!feof(fp)){
            len = fread(buffer, 1, sizeof(buffer), fp);
            int bflen = write(client_sock, buffer, len);
            totalbytes += len;
            printf("write in bytes:%d, total written bytes:%d\n", bflen, totalbytes);
        }
        printf("write done, total bytes:%d\n", totalbytes);
    }
    close(sock);
    return 0;
}

tcp客户端:

以二进制的方式接收文件

//是否从服务器上下载资源文件
#define download_rcc_from_remote_server 1

void DownloadService::downloadfromserver() {

#if download_rcc_from_remote_server
#ifdef WIN32
    WORD sockVersion = MAKEWORD(2, 2);
	WSADATA wsaData;
	if (WSAStartup(sockVersion, &wsaData) != 0)
	{
		return;
	}
#elif 1
#define INVALID_SOCKET ~0
#endif

    struct sockaddr_in server_sock;
    int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    memset(&server_sock, 0, sizeof(server_sock));
    server_sock.sin_family = AF_INET;
#ifdef WIN32
    inet_pton(AF_INET, SERVER_IP, &server_sock.sin_addr);
#elif
    inet_pton(AF_INET, SERVER_IP, &server_sock.sin_addr);
#endif
    server_sock.sin_port = htons(SERVER_PORT);

    int ret = ::connect(sock, (struct sockaddr*)&server_sock, sizeof(server_sock));
    if(ret < 0)
    {
        printf("connect failed...,errno is %d,errstring is %s\n",errno,strerror(errno));
    }
    qDebug("connect is success...\n");
    #ifdef WIN32
    send(sock, "download", 9, 0);
    #elif 1
    write(sock, buf, strlen(buf) + 1);
    #endif
    FILE *pf;
    pf = fopen("./maroon.rcc", "w+");
    fclose(pf);
    pf = fopen("./maroon.rcc", "wb");
    int tl = 0;
    int timeout = 1500;
    //设置接收超时时间
    setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(int));
    int i = 0;
    while(true) {
        char recvBuf[4096] = { 0 };
         #ifdef WIN32
        int len = recv(sock, recvBuf, 4096, 0);
        #elif 1
        read(sock,buf,sizeof(buf));
        #endif
        if(len <= 0)
            break;

        tl += len;
        qDebug() << "recv rcc part:" << len << ", total bytes:" << tl;
        fwrite(recvBuf, len, 1, pf);
    }
    qDebug() << "recv done";
    fclose(pf);
#ifdef WIN32
    WSACleanup();
#elif
    close(sock);
#endif
#endif
    emit plugindownfinished(true);
}