TCP通信

服务端

// socketclint.cpp : 定义控制台应用程序的入口点。
 
#include <stdio.h>
#include "conio.h"
//#include "winsock.h"
#include<winsock2.h>
#include "windows.h"

#pragma comment(lib, "ws2_32.lib")
 
//#define MAX_SOCKET 65535*5

struct  tcp_keepalive  {
    u_long    onoff;
    u_long    keepalivetime;
    u_long    keepaliveinterval;
};
#define  SIO_RCVALL                  _WSAIOW(IOC_VENDOR,1)
#define  SIO_RCVALL_MCAST            _WSAIOW(IOC_VENDOR,2)
#define  SIO_RCVALL_IGMPMCAST        _WSAIOW(IOC_VENDOR,3)
#define  SIO_KEEPALIVE_VALS          _WSAIOW(IOC_VENDOR,4)
#define  SIO_ABSORB_RTRALERT          _WSAIOW(IOC_VENDOR,5)
#define  SIO_UCAST_IF                _WSAIOW(IOC_VENDOR,6)
#define  SIO_LIMIT_BROADCASTS        _WSAIOW(IOC_VENDOR,7)
#define  SIO_INDEX_BIND              _WSAIOW(IOC_VENDOR,8)
#define  SIO_INDEX_MCASTIF            _WSAIOW(IOC_VENDOR,9)
#define  SIO_INDEX_ADD_MCAST          _WSAIOW(IOC_VENDOR,10)
#define  SIO_INDEX_DEL_MCAST          _WSAIOW(IOC_VENDOR,11)

//上面的结构体和define是#include <mstcpip.h> 的内容
int socket_set_keepalive (int fd)
{
#ifdef WIN32
    struct tcp_keepalive kavars;
    struct tcp_keepalive alive_out;
    kavars.onoff = TRUE;
    kavars.keepalivetime = 30*1000;
    kavars.keepaliveinterval = 6*000;

    /* Set: use keepalive on fd */
    int alive = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char *) &alive,sizeof alive) != 0)
    {
        return -1;
    }

    unsigned long ulBytesReturn = 0;
    WSAIoctl(fd, SIO_KEEPALIVE_VALS, &kavars, sizeof(kavars),&alive_out, sizeof(alive_out), &ulBytesReturn, NULL, NULL);
#else
    int keepAlive = 1;    // 非0值,开启keepalive属性
    int keepIdle = 30;    // 如该连接在60秒内没有任何数据往来,则进行此TCP层的探测
    int keepInterval = 5; // 探测发包间隔为5秒
    int keepCount = 3;        // 尝试探测的最多次数

    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
    setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
    setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
    setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
#endif
    return 0;
}

int startup(int _port,const char* _ip)
{
    WSADATA ws;
    WSAStartup(MAKEWORD(2,2),&ws);
    int sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sock < 0)
    {
        perror("socket");
        exit(1);
    }

    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons( _port);
    local.sin_addr.s_addr = inet_addr(_ip);
    int len = sizeof(local);

    //int opt_val=MAX_SOCKET;
    //int opt_len = sizeof(opt_val);
    //setsockopt(sock,SOL_SOCKET,SO_SNDBUF,(char *)&opt_val,4);//设置缓存大小

    if(bind(sock,(struct sockaddr*)&local , len) < 0)
    {
        perror("bind");
        exit(2);
    }

    if(listen(sock, 5) < 0) //允许连接的最大数量为5
    {
        perror("listen");
        exit(3);
    }

    return sock;
}


int main()
{
    int listen_sock = startup(6000,"127.0.0.1");//初始化

    //用来接收客户端的socket地址结构体
    struct sockaddr_in remote;
    int len = sizeof(struct sockaddr_in);

    while(1)
    {
        int sock = accept(listen_sock, (struct sockaddr*)&remote, &len);
        if(sock < 0)
        {
            perror("accept\n");
            continue;
        }

        int n = socket_set_keepalive (sock);
        if (n <0 )
        {
            return -1;
        }
        //printf("get a client, ip:%s, port:%d\n",inet_ntoa(remote.sin_addr),ntohs(remote.sin_port));
        char buf[1024];
        char bufRecv[1024];
        while(1)
        {
            memset(buf,0,sizeof(buf));            
            memset(bufRecv,0,sizeof(bufRecv));
            int len =  recv(sock, bufRecv, sizeof(bufRecv)-1,0);

            if(len > 0)
            {
                printf("recv:%s\n",bufRecv);
            }
            else
            {
                printf("client is quit!\n");
                break;
            }
        }
    }
    return 0;
}
 

客户端:

#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc,const char* argv[])
{
    //if(argc != 3)
    //{
    //    printf("Usage:%s [ip] [port]\n",argv[0]);
    //    return 0;
    //}
    WSADATA ws;
    WSAStartup(MAKEWORD(2,2),&ws);
    //创建一个用来通讯的socket
    int sock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
    if(sock < 0)
    {
        perror("socket");
        return 1;
    }

    //需要connect的是对端的地址,因此这里定义服务器端的地址结构体
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port =htons(6000);
    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    //server.sin_port = htons(atoi(argv[2]));
    //server.sin_addr.s_addr = inet_addr(argv[1]);
    int len = sizeof(struct sockaddr_in);
    if(connect(sock, (struct sockaddr*)&server, len) < 0 )
    {
        perror("connect");
        return 2;
    }
    //连接成功进行收数据
    char buf[1024];
    
    while(1)
    {      
        memset(buf,0,sizeof(buf));
        sprintf(buf,"%s","hello world");
        int _s = send(sock, buf, strlen(buf),0);
        Sleep(100);
    }
    closesocket(sock);;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jena_wy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值