windows c编写TCP通信

一、介紹
有時候需要用windows写点小工具需要用到tcpip,这里介绍在dev c++下编写网络通信

流程和linux差不多
1、使用WSAStartup()函数检查系统协议栈安装情况
2、使用socket()函数创建服务器端通信套接字
3、使用bind()函数将创建的套接字与服务器地址绑定
4、使用listen()函数使服务器套接字做好接收连接请求准备
5、使用accept()接收来自客户端由connect()函数发出的连接请
6、根据连接请求建立连接后,使用send()函数发送数据,或者使7、用recv()函数接收数据
8、使用closesocket()函数关闭套接字(可以先用shutdown()函数9、先关闭读写通道)
10、最后调用WSACleanup()函数结束Winsock Sockets API

二、工程配置
添加库libws2_32.a
在这里插入图片描述
三、tcp 客户端
tcp.c

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")

static SOCKET sClient;
#define CLENT_NUM 1
static SOCKET sSever,sSever_c[CLENT_NUM];
struct sockaddr_in sSever_c_sd[CLENT_NUM];

#define USER_ERROR -1

int tcp_client_init(char *ip, int iPort)
{
    struct sockaddr_in ser; //服务器端地址
    WSADATA wsaData;

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf("Failed to load Winsock.\n"); //Winsock 初始化错误
        return -1;
    }
    ser.sin_family = AF_INET;                        //初始化服务器地址信息
    ser.sin_port = htons(iPort);                     //端口转换为网络字节序
    ser.sin_addr.s_addr = inet_addr(ip); //IP 地址转换为网络字节序
    sClient = socket(AF_INET, SOCK_STREAM, 0);       //创建客户端流式套接字
    if (sClient == INVALID_SOCKET)
    {
        printf("socket() Failed: %d\n", WSAGetLastError());
        return -1;
    }
    //请求与服务器端建立 TCP 连接
    if (connect(sClient, (struct sockaddr *)&ser, sizeof(ser)) == INVALID_SOCKET)
    {
        printf("connect() Failed: %d\n", WSAGetLastError());
        return -1;
    }
    printf("connect ok\n"); 

    return 0;
}

int tcp_client_send(unsigned char *buff, int len)
{
    send(sClient, buff, len, 0);
}

int tcp_client_rcv(unsigned char *buff, int *len)
{
    int iLen; //从服务器端接收的数据长度

    iLen = recv(sClient, buff, 1024, 0); //从服务器端接收数据
    if (iLen == 0)
        return -1;
    else if (iLen == SOCKET_ERROR)
    {
        printf("recv() Failed: %d\n", WSAGetLastError());
        return -1;
    }
    else
        printf("recv() data from server: %s\n", buff); // 输出接收数据
    *len = iLen;

    return iLen;
}

int close_tcp_client()
{
    closesocket(sClient); //关闭 socket
    WSACleanup();
}

tcp.h

#ifndef __TCP_H
#define __TCP_H

int tcp_client_init(char *ip, int iPort);
int tcp_client_send(unsigned char *buff, int len);
int tcp_client_rcv(unsigned char *buff, int *len);
int close_tcp_client();
#endif

main.c

#include <stdio.h>
#include "tcp.h"

int tcp_client_test()
{
    unsigned char buff[1024] = {0};
    int rcv_len;

    tcp_client_init("192.168.3.65", 1000);
    while(1)
    {
        memset(buff, 0 , 1024);
        rcv_len = tcp_client_rcv(buff, &rcv_len);
        if(rcv_len > 0)
        printf("rcv:%s\n", buff);
        tcp_client_send(buff, rcv_len);
    }
}

int main(int argc, char *argv[])
{
    tcp_client_test();
    return 0;
}

在这里插入图片描述

四、tcp服务端
tcp.c

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")

#define CLENT_NUM 2

static SOCKET sSever,sSever_c[CLENT_NUM];
static SOCKET sSever_c1;
struct sockaddr_in sSever_c_sd[CLENT_NUM],sSever_c_sd1;

#define USER_ERROR -1

int ip_invalid(unsigned char *s)
{
    if(s[0] == 0 && s[1] == 0 
    &&s[2] == 0 && s[3] == 0)
        return 1;
    else
        return 0;
}

int tcp_server_init(int iPort)
{
    struct sockaddr_in ser; //服务器端地址
    WSADATA wsaData;
    int i;
    int addrlen;

    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf("Failed to load Winsock.\n");
        return USER_ERROR;
    }
    ser.sin_family = AF_INET;                        //初始化服务器地址信息
    ser.sin_port = htons(iPort);                     //端口转换为网络字节序
    //ser.sin_addr.s_addr = htonl(INADDR_ANY);//
    ser.sin_addr.s_addr = inet_addr("192.168.3.65");//
    //ser.sin_addr.S_un.S_addr = INADDR_ANY;
    sSever = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);       //创建客户端流式套接字
    if(sSever == INVALID_SOCKET)
    {
        printf("socket() Failed: %d\n", WSAGetLastError());
        return -1;
    }
    if(bind(sSever, (LPSOCKADDR)&ser, sizeof(ser)) == SOCKET_ERROR)
    {
        printf("blind() Failed:%d\n", WSAGetLastError());
        return USER_ERROR;
    }
    if(listen(sSever, 5) == SOCKET_ERROR)
    {
        printf("listen() Failed:%d\n", WSAGetLastError());
        return USER_ERROR;
    }
    addrlen = sizeof(struct sockaddr_in);
    printf("create server ok\nip: %s,port:%d\n",inet_ntoa(ser.sin_addr), ntohs(ser.sin_port));
    printf("wait link \n");
 //   sSever_c1 = accept(sSever, (SOCKADDR *)&sSever_c_sd1, &addrlen);
 //   printf("link a client ip:%s,port:%d\n",inet_ntoa(sSever_c_sd1.sin_addr),sSever_c_sd1.sin_port);
 
#if 1     
    for ( i = 0; i < CLENT_NUM; i++)
    {
        while(sSever_c[i] == INVALID_SOCKET)
        {
            sSever_c[i] = accept(sSever, (SOCKADDR *)&sSever_c_sd[i], &addrlen);
            printf("error\n");
        }
        printf("link a client ip:%s,port:%d\n",inet_ntoa(sSever_c_sd[i].sin_addr),sSever_c_sd[i].sin_port);
    }
#endif
	printf("link ok\n");

    return 0;
}


int tcp_server_send(char c, unsigned char *buff, int len)
{
    send(sSever_c[c], buff, len, 0);

    return 0;
}

int tcp_server_rcv(char c, unsigned char *buff, int *len)
{
    int ret,i;

    ret = recv(sSever_c[c], buff, 1024, 0);
    *len = ret;

    return ret;
}

int close_tcp_server()
{
    closesocket(sSever);
    WSACleanup();
}

tcp.h

#ifndef __TCP_H
#define __TCP_H

int tcp_server_init( int iPort);
int tcp_server_send(char c, unsigned char *buff, int len);
int tcp_server_rcv(char c, unsigned char *buff, int *len);
int close_tcp_server();

#endif

main.c

#include <stdio.h>
#include "tcp.h"

int tcp_server_test()
{
    unsigned char buff[1024] = {0};
    int rcv_len;

    tcp_server_init(2000);
    while(1)
    {
        memset(buff, 0 , 1024);
        rcv_len = tcp_server_rcv(0, buff, &rcv_len);
        if(rcv_len > 0)
        {
            printf("rcv:%s\n", buff);
            tcp_server_send(0, buff, rcv_len);
        }
        
    }
}

int main(int argc, char *argv[])
{
    tcp_server_test();

    return 0;
}

结果:待更新

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值