socket编程代码示例

news/2025/1/16 6:32:11/

1. TCP server client模拟聊天对话框

server.c

/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define BUFFER_SIZE (1024)
#define IP_SIZE (100)
#define SERVER_SUCCESS (0)
#define SERVER_FAILURE (-1)
#define MAX_PENDDING_QUEUE (10)typedef enum {false = 0,true = 1,
} bool;static void server_usage(void)
{printf("#####################################\n");printf("#Server Usage:                      #\n");printf("#gcc server.c -o server             #\n");printf("#chmod 777 server                   #\n");printf("#./server <ip> <port>               #\n");printf("#                                   #\n");printf("#<ip>:server ip:192.168.xx.xx       #\n");printf("#<port>:server port:1024~65535      #\n");printf("#####################################\n");return;
}int main(int argc, char *argv[])
{int listenfd = -1;int connectfd = -1;int ret;int recv_bytes;struct sockaddr_in serveraddr;struct sockaddr_in clientaddr;socklen_t peerlen;char server_buf[BUFFER_SIZE] = {0};char client_addr[IP_SIZE] = {0};if (argc < 3) {server_usage();return SERVER_FAILURE;}/* socket */listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd == -1) {printf("[ERROR]server socket failed, why:%s\n", strerror(errno));return SERVER_FAILURE;}printf("[DEBUG]server socket success, listenfd = %d\n", listenfd);/* serveraddr */memset(&serveraddr, 0x00, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);/* bind */ret = bind(listenfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr));if (ret != 0) {printf("[ERROR]server bind failed, why:%s\n", strerror(errno));close(listenfd);return SERVER_FAILURE;}printf("[DEBUG]server bind success\n");/* listen */ret = listen(listenfd, MAX_PENDDING_QUEUE);if (ret != 0) {printf("[ERROR]server listen failed, why:%s\n", strerror(errno));close(listenfd);return SERVER_FAILURE;}printf("[DEBUG]server listen success\n");printf("server waiting for connect......\n\n");/* accept */while (true) {memset(&clientaddr, 0x00, sizeof(clientaddr));peerlen = sizeof(clientaddr);connectfd = accept(listenfd, (struct sockaddr *)&clientaddr, &peerlen);if (connectfd == -1) {printf("[ERROR]server accept failed, why:%s\n", strerror(errno));close(listenfd);return SERVER_FAILURE;}memset(client_addr, 0x00, sizeof(client_addr));inet_ntop(AF_INET, &clientaddr.sin_addr, client_addr, sizeof(client_addr));printf("[DEBUG]server connected, client ip:%s, port:%d\n\n", client_addr, ntohs(clientaddr.sin_port));/* send and recv */while (true) {memset(server_buf, 0x00, sizeof(server_buf));printf("\033[1m<--- \033[0m"), fflush(stdout);recv_bytes = recv(connectfd, server_buf, sizeof(server_buf), 0);if (recv_bytes == -1) {printf("[ERROR]server recv failed, why:%s\n", strerror(errno));close(connectfd);close(listenfd);return SERVER_FAILURE;} else if (recv_bytes == 0) {printf("[DEBUG]server detected client gone!\n");close(connectfd);break;}printf("client@%s:%d said:%s\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), server_buf);memset(server_buf, 0x00, sizeof(server_buf));printf("\033[1m---> \033[0m"), fflush(stdout);fgets(server_buf, sizeof(server_buf), stdin);send(connectfd, server_buf, sizeof(server_buf), 0);printf("\n");}}close(listenfd);return SERVER_SUCCESS;
}

client.c

/* client.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define BUFFER_SIZE (1024)
#define CLIENT_SUCCESS (0)
#define CLIENT_FAILURE (-1)
#define MAX_PENDDING_QUEUE (10)typedef enum {false = 0,true = 1,
} bool;static void client_usage(void)
{printf("#####################################\n");printf("#Client Usage:                      #\n");printf("#gcc client.c -o client             #\n");printf("#chmod 777 client                   #\n");printf("#./client <ip> <port>               #\n");printf("#                                   #\n");printf("#<ip>:server ip:192.168.xx.xx       #\n");printf("#<port>:server port:1024~65535      #\n");printf("#####################################\n");return;
}int main(int argc, char *argv[])
{int sockfd = -1;int ret;int recv_bytes;struct sockaddr_in serveraddr;char client_buf[BUFFER_SIZE] = {0};if (argc < 3) {client_usage();return CLIENT_FAILURE;}/* socket */sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {printf("[ERROR]client socket failed, why:%s\n", strerror(errno));return CLIENT_FAILURE;}printf("[DEBUG]client socket success, sockfd = %d\n", sockfd);/* serveraddr */memset(&serveraddr, 0x00, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);ret = connect(sockfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr));if (ret == -1) {printf("[ERROR]client connect failed, why:%s\n", strerror(errno));close(sockfd);return CLIENT_FAILURE;}printf("[DEBUG]client connect success\n");while (true) {memset(client_buf, 0x00, sizeof(client_buf));printf("\033[1m---> \033[0m"), fflush(stdout);fgets(client_buf, sizeof(client_buf), stdin);printf("\n");/* client said quit */if (strncmp(client_buf, "quit!", strlen("quit!")) == 0) {printf("[DEBUG]client said %s\n", client_buf);break;}send(sockfd, client_buf, sizeof(client_buf), 0);memset(client_buf, 0x00, sizeof(client_buf));printf("\033[1m<--- \033[0m"), fflush(stdout);recv_bytes = recv(sockfd, client_buf, sizeof(client_buf), 0);if (recv_bytes == -1) {printf("[ERROR]client recv failed, why:%s\n", strerror(errno));close(sockfd);return CLIENT_FAILURE;} else if(recv_bytes == 0) {printf("[DEBUG]client detected server gone!\n");break;}printf("server@%s:%d said:%s\n", argv[1], atoi(argv[2]), client_buf);}close(sockfd);printf("[DEBUG]<=====client exit\n");return CLIENT_SUCCESS;
}

wireshark抓包结果:

2. 用原始套接字模拟ping操作并解析IP包与ICMP包

//This is a ping which can both send and receive ICMP packets
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/tcp.h>
#include <netinet/ip_icmp.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>#define PING_SUCCESS (0)
#define PING_FAILURE (-1)
#define BUFFER_SIZE (1024)
#define MAGIC_NUM (3623)
//#define DEBUGstatic unsigned short calc_cksum(unsigned short *addr, int len)
{int sum=0;unsigned short res=0;while( len > 1) {sum += *addr++;len -= 2;}if( len == 1) {*((unsigned char *)(&res))=*((unsigned char *)addr);sum += res;}sum = (sum >>16) + (sum & 0xffff);sum += (sum >>16) ;res = ~sum;return res;
}int main(int argc, char *argv[])
{if (argc < 4) {printf("param error, usage: ./ping serverip -c <count>\n");return PING_FAILURE;}int count = atoi(argv[3]);char send_buff[BUFFER_SIZE] = {0};char recv_buff[BUFFER_SIZE] = {0};char src_buff[BUFFER_SIZE] = {0};int sockfd = -1;int recvfd = -1;int ret, i, lenfrom;struct sockaddr_in target_addr;struct sockaddr_in source_addr;/* socket */sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (sockfd == -1) {printf("sockfd create for IPPROTO_ICMP failed, why:%s\n", strerror(errno));return PING_FAILURE;}recvfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (recvfd == -1) {printf("recvfd create for IPPROTO_ICMP failed, why:%s\n", strerror(errno));close(sockfd);return PING_FAILURE;}#ifdef DEBUGprintf("[DEBUG]socket create for IPPROTO_ICMP success\n");
#endifmemset(&target_addr, 0x00, sizeof(target_addr));ret = inet_pton(AF_INET, argv[1], &target_addr.sin_addr);if (ret != 1) {printf("bad ip address to be converted:%s\n", argv[1]);close(recvfd);close(sockfd);return PING_FAILURE;}struct icmp *picmp = (struct icmp *)send_buff;struct ip *pip = (struct ip*)recv_buff;struct icmp *p_recvicmp = (struct icmp *)(pip + 1);for (i = 0; i < count; i++) {memset(send_buff, 0x00, sizeof(send_buff));/*----TYPE----CODE----CHECKSUM----*----IDENTIFIER------SEQUENCE----*----OPTION----------------------*/picmp->icmp_type = ICMP_ECHO; /* ECHO-REQUEST */picmp->icmp_code = 0;picmp->icmp_id = MAGIC_NUM;picmp->icmp_seq = i;picmp->icmp_cksum = calc_cksum((unsigned short *)picmp, 8);/* PING REQUEST */ret = sendto(sockfd, send_buff, 64, 0, (const struct sockaddr *)&target_addr, sizeof(target_addr)); /* ICMP total 64 bytes */if (ret == -1) {printf("turn %d sendto error, why:%s\n", i, strerror(errno));close(recvfd);close(sockfd);return PING_FAILURE;}#ifdef DEBUGprintf("[DEBUG]turn %d, %d bytes send...\n", i, ret);
#endif/* PING REPLY */memset(recv_buff, 0x00, sizeof(recv_buff));memset(&source_addr, 0x00, sizeof(source_addr));lenfrom = sizeof(source_addr);ret = recvfrom(sockfd, recv_buff, sizeof(recv_buff), 0, (struct sockaddr *)&source_addr, &lenfrom);if (ret == -1) {printf("turn %d recvfrom error, why:%s\n", i, strerror(errno));close(recvfd);close(sockfd);return PING_FAILURE;} else if (ret == 0) {printf("turn %d detect socket peer shutdown!\n", i);close(recvfd);close(sockfd);return PING_FAILURE;}#ifdef DEBUGprintf("[DEBUG]turn %d, %d bytes recv\n", i, ret);printf("[DEBUG]recv ip header len = %d\n", pip->ip_hl);
#endifif ((ret - (pip->ip_hl * 4)) < 8) { /* we assume ICMP at least 8 byte */printf("turn %d no ICMP reply!\n", i);close(recvfd);close(sockfd);return PING_FAILURE;}if ((p_recvicmp->icmp_type == ICMP_ECHOREPLY) && (p_recvicmp->icmp_id == MAGIC_NUM)) {/* get the src and dst addr */memset(src_buff, 0x00, sizeof(src_buff));/* from where? */inet_ntop(AF_INET, &source_addr.sin_addr, src_buff, sizeof(src_buff));printf("[myping]%d bytes from %s to %s: icmp_seq=%u ttl=%d\n", (ret-(pip->ip_hl * 4)), (src_buff), (inet_ntoa(pip->ip_dst)), (p_recvicmp->icmp_seq), (pip->ip_ttl));} else {printf("[myping]recv no wanted packet!\n");continue;}}printf("done!\n");close(recvfd);close(sockfd);return PING_SUCCESS;
}

 wireshark抓包结果:

 


http://www.ppmy.cn/news/958482.html

相关文章

Xshell 7 评估期已过继续免费使用方法

1. 评估期已过的示例 2.解决方法 如果需要继续使用&#xff0c;一是去网上寻找绿色版本的Xshell&#xff0c;但是可能不安全。 二是重新下载一个免费版本&#xff0c;覆盖安装即可。 2.1 官网下载地址&#xff1a;https://www.xshell.com/zh/free-for-home-school/ 2.2下载安…

java工作随笔

String s JSONObject.toJSONString(fixedAsset);logger.error("-----------------8------------------" s);CusFixedAssettDTO CusFixedAssettDTO3 JSONObject.parseObject(s, CusFixedAssettDTO.class);父类转子类 相同对象合并 import java.util.Date; Data T…

访谈 guyskk:做出了个有稳定收益的小程序的故事

自我介绍 大家好&#xff0c;我可以称呼我guyskk。上下班的日子差不多有3年&#xff0c;最后一家公司是Paypal。独立开发做了 2 年&#xff0c;做过的产品有“蚁阅\艺爪\chatgpt小程序【超级AI】”&#xff0c;不过做的产品收益都不高&#xff0c;目前还不能养活自己。现在的状…

生成式AI发现潜在抗癌药物;王慧文与“一流科技”达成并购意向;阿里巴巴公布六大业务集团CEO丨每日大事件...

‍ ‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 企业动态 阿里巴巴公布六大业务集团CEO&#xff1a;张勇兼任阿里云智能集团CEO 3月28日&#xff0c;阿里巴巴集团董事会主席兼首席执行官张勇发布全员信&#xff0c;宣布启动“16N”组织变革。根据全员信&#xff0c;张勇…

优雅的接口防刷处理方案

大家好&#xff0c;我是老赵! 本文为描述通过Interceptor以及Redis实现接口访问防刷Demo 这里会通过逐步找问题&#xff0c;逐步去完善的形式展示 原理 通过ip地址uri拼接用以作为访问者访问接口区分通过在Interceptor中拦截请求&#xff0c;从Redis中统计用户访问接口次数从而…

爆火的 Auto-GPT 被过分吹捧了!

整理 | 王子彧 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; Jina AI 的创始人兼 CEO 肖涵发布的《揭秘 Auto-GPT 喧嚣背后的残酷真相&#xff01;》一文中&#xff0c;肖涵博士表示道&#xff1a;想要在现实的生产环境中使用 Auto-GPT&#xff0c;首先面临的障…

雷军:小米汽车争取15-20年进入世界前五;GitHub宣布裁员10%,全员转远程办公;谷歌AR/VR负责人宣布离职|极客头条...

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&#…

快来!Claude无需魔法不限量;百度官方AIGC公开课;Prompt高质量答案完全指南;GPT-5真的要来了?贾扬清离职阿里后首次受访 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『3月AI大事记&干货集』4月国内互联网持续发力中&#xff0c;精彩精彩 &#x1f916; 『GPT-4.5/GPT-5真的要来了&#xff1f;』怎…