赞
踩
目录
- #ifndef __PORT_H__
- #define __PORT_H__
-
- #include <stdint.h>
- #define SERVERIP "x.x.x.x"
- #define SERVERPORT 1999
- #define MSGSIZE 1024
-
- #define handler_error(msg)\
- do {perror(msg); exit(EXIT_FAILURE);} while(0)
- struct __msg{
- int8_t id;
- char msg[MSGSIZE];
- }__attribute__((packed));
-
- typedef struct __msg msg_t;
-
-
-
- #endif
- // Date:2023.09.14 19:51:14
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <string.h>
- #include "port.h"
- /* 客户端 */
- int main(int argc, char *argv[])
- {
- int cnt;
- int udp_socket;
- struct sockaddr_in addr_in;
- msg_t sendbuf;
- socklen_t addr_len;
-
- if (argc < 3)
- exit(1);
-
- // 创建报式套接子
- if(-1 == (udp_socket = socket(AF_INET, SOCK_DGRAM, 0)))
- handler_error("socket()");
-
- // bind可省略
-
- // 发送的数据
- sendbuf.id = atoi(argv[1]);
- strncpy(sendbuf.msg, argv[2], MSGSIZE);
- // server地址
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(SERVERPORT);
- addr_in.sin_addr.s_addr = inet_addr(SERVERIP);
- //inet_aton(SERVERIP, &addr_in.sin_addr);
-
- if(-1 == sendto(udp_socket, &sendbuf, sizeof(sendbuf.id)+strlen(sendbuf.msg)+1, 0,\
- (struct sockaddr *)&addr_in, sizeof(addr_in))){
- close(udp_socket); handler_error("sendto()");
- }
- memset(sendbuf.msg, '\0', MSGSIZE);
- if(-1 == recvfrom(udp_socket, &sendbuf, sizeof(sendbuf), 0, NULL, NULL)){
- close(udp_socket); handler_error("recvfrom()");
- }
-
- // 请求后得到服务器反馈
- printf("%d , %s \n", sendbuf.id, sendbuf.msg);
-
- close(udp_socket);
-
- return 0;
- }
- // Date:2023.09.14 19:51:14
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <string.h>
- #include "port.h"
- /* 服务端 */
- int main(void)
- {
- int cnt;
- int udp_socket;
- struct sockaddr_in addr_in, client_addr;
- msg_t rcvbuf;
- socklen_t client_addr_len;
- if(-1 == (udp_socket = socket(AF_INET, SOCK_DGRAM, 0)))
- handler_error("socket()");
-
- // 绑定地址
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(SERVERPORT);
- // 点分十进制ip转换为ip结构体
- //addr_in.sin_addr.s_addr = inet_addr(SERVERIP);
- inet_aton(SERVERIP, &addr_in.sin_addr);
- if(-1 == bind(udp_socket, (struct sockaddr *)&addr_in, sizeof(addr_in))){
- close(udp_socket); handler_error("bind()");
- }
- // 接受client的数据包之前一定要将地址长度赋值
- client_addr_len = sizeof(struct sockaddr_in);
-
- while(1){
- // 等待接受客户端请求
- if(-1 == (cnt = recvfrom(udp_socket, &rcvbuf, sizeof(rcvbuf), 0, (struct sockaddr *)&client_addr, &client_addr_len))){
- close(udp_socket); handler_error("recvfrom()");
- }
- // 调试语句
- printf("[%s][%d] ", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
- printf("id:%d , msg: %s\n", rcvbuf.id, rcvbuf.msg);
-
- // 向客户端发送数据
- rcvbuf.id = 0;
- strcpy(rcvbuf.msg, "ok");
- sendto(udp_socket, &rcvbuf, sizeof(rcvbuf.id) + strlen(rcvbuf.msg) + 1,0, (struct sockaddr *)&client_addr, client_addr_len);
-
- }
- close(udp_socket);
-
- return 0;
- }
在编写 UDP 程序时,你需要关注数据包的大小、分片和重组、丢包处理等问题,因为 UDP 本身不提供这些功能。此外,UDP 也不提供拥塞控制,因此在高负载或不稳定的网络环境中,可能会导致丢包和延迟增加。
- #ifndef __GROUP_PROTO_H__
- #define __GROUP_PROTO_H__
-
- // 多播组 接受端口
- #define GROUP_IP "224.2.3.4"
- #define RCV_PORT 1314
-
- // 数据类型
- #define MAX_MSG 1024
-
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <arpa/inet.h>
- #include <net/if.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include "group_proto.h"
- /* 客户端 */
- int main(void)
- {
- int udp_socket;
- struct sockaddr_in myaddr; // man 7 ip
- struct ip_mreqn imr;
- char *buf = NULL;
- int cnt;
-
- udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
- if (-1 == udp_socket) {
- perror("socket()");
- exit(1);
- }
-
- // 被动端需要bind地址
- myaddr.sin_family = AF_INET;
- myaddr.sin_port = htons(RCV_PORT);
- inet_aton("0.0.0.0"/*INADDR_ANY*/, &myaddr.sin_addr);
- if (-1 == bind(udp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
- perror("bind()");
- goto ERROR1;
- }
-
- // 加入多播组
- inet_aton(GROUP_IP, &imr.imr_multiaddr);
- // 注意INADDR_ANY不是字符串,是uint32_t整型数
- inet_aton("0.0.0.0", &imr.imr_address);
- // 虚拟网卡的索引值,索引名转换为值if_nametoindex(3)
- imr.imr_ifindex = if_nametoindex("ens33");
- if (-1 == setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr))) {
- perror("setsockopt()");
- goto ERROR1;
- }
-
- // 接受消息
- buf = malloc(MAX_MSG);
- // if error
- while (1) {
- memset(buf, '\0', MAX_MSG);
- cnt = recvfrom(udp_socket, buf, MAX_MSG, 0, NULL, NULL);
- if (-1 == cnt) {
- perror("recvfrom()");
- goto ERROR1;
- }
- if (strcmp(buf, "bye") == 0)
- break;
- puts(buf);
- }
-
- close(udp_socket);
- free(buf);
- buf = NULL;
-
- exit(0);
- ERROR1:
- close(udp_socket);
- exit(1);
- }
- #include <stdio.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <arpa/inet.h>
- #include <net/if.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include "group_proto.h"
- /* 服务端 */
- int main(void)
- {
- int udp_socket;
- struct sockaddr_in snd_addr; // man 7 ip
- struct ip_mreqn imr;
-
- udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
- if (-1 == udp_socket) {
- perror("socket()");
- exit(1);
- }
-
- // 将本地设备设置为多播
- inet_aton(GROUP_IP, &imr.imr_multiaddr);
- imr.imr_address.s_addr = INADDR_ANY;
- // inet_aton("0.0.0.0", &imr.imr_address);
- // 虚拟网卡的索引值,索引名转换为值if_nametoindex(3)
- imr.imr_ifindex = if_nametoindex("ens33");
- if (-1 == setsockopt(udp_socket, IPPROTO_IP, IP_MULTICAST_IF, &imr, sizeof(imr))) {
- perror("setsockopt()");
- goto ERROR1;
- }
- printf("[%d]debug...\n", __LINE__);
-
- // 发送消息
- snd_addr.sin_family = AF_INET;
- snd_addr.sin_port = htons(RCV_PORT);
- inet_aton(GROUP_IP, &snd_addr.sin_addr);
- while (1) {
- sendto(udp_socket, "hello", 5, 0, (struct sockaddr *)&snd_addr, sizeof(snd_addr));
- sleep(1);
- }
-
- close(udp_socket);
-
- exit(0);
- ERROR1:
- close(udp_socket);
- exit(1);
- }
- #ifndef __TCP_PROT_H__
- #define __TCP_PROT_H__
-
- // server地址(ip + port)
- #define SERVER_IP "x.x.x.x"
- #define SERVER_PORT 3344
-
- // 对话格式(数据类型)
- #define MAXMSG 1024
-
- struct msg_st {
- char msg[MAXMSG];
- }__attribute__((packed));
-
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #include <unistd.h>
-
- #include "tcp_proto.h"
- /* 客户端 */
- int main(void)
- {
- int tcp_socket;
- struct sockaddr_in server_addr;
- struct msg_st rcvbuf;
- int cnt;
-
- // 创建流式套接字
- tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == tcp_socket) {
- perror("socket()");
- exit(1);
- }
-
- // 请求与服务器连接
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(SERVER_PORT);
- inet_aton(SERVER_IP, &server_addr.sin_addr);
- if (-1 == connect(tcp_socket, (struct sockaddr *)&server_addr, sizeof(server_addr))) {
- perror("connect()");
- goto ERROR;
- }
-
- // 接受
- memset(rcvbuf.msg, '\0', MAXMSG);
- cnt = read(tcp_socket, &rcvbuf, MAXMSG);
- printf("from server rcv msg:%s with %dbytes\n", rcvbuf.msg, cnt);
-
- close(tcp_socket);
-
- exit(0);
- ERROR:
- close(tcp_socket);
- exit(1);
- }
- #include <stdio.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #include <unistd.h>
-
- #include "tcp_proto.h"
- /* 服务端 */
- int main(void)
- {
- int tcp_socket, accepted_socket;
- struct sockaddr_in myaddr;
- pid_t pid;
-
- // 创建流式套接字
- tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == tcp_socket) {
- perror("socket()");
- exit(1);
- }
-
- // 绑定本地地址
- myaddr.sin_family = AF_INET;
- myaddr.sin_port = htons(SERVER_PORT);
- myaddr.sin_addr.s_addr = INADDR_ANY;
- if (-1 == bind(tcp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
- perror("bind()");
- goto ERROR;
- }
-
- // 套接字处于监听状态
- if (-1 == listen(tcp_socket, 200)) {
- perror("listen()");
- goto ERROR;
- }
-
- // sigaction(SIGCHLD, ); SA_NOCHLDWAIT
-
- while (1) {
- // 等待接受客户端的连接请求
- accepted_socket = accept(tcp_socket, NULL, NULL);
- if (-1 == accepted_socket) {
- perror("accept()");
- goto ERROR;
- }
- // 成功后accepted_socket就是用于数据交换的套接字 原来的tcp_socket是用于继续接受客户端连接请求的
- pid = fork();
- if (-1 == pid) {
- perror("fork()");
- goto ERROR;
- }
- if (0 == pid) {
- // 数据交换 用accepted_socket
- close(tcp_socket);
- sleep(1);
- write(accepted_socket, "can you see that?", 17);
- close(accepted_socket);
- exit(0);
- }
- close(accepted_socket);
- }
-
- close(tcp_socket);
-
- exit(0);
- ERROR:
- close(tcp_socket);
- exit(1);
- }
- #ifndef __TCP_PROT_H__
- #define __TCP_PROT_H__
-
- // server地址(ip + port)
- #define SERVER_IP "x.x.x.x"
- #define SERVER_PORT 3344
-
- // 对话格式(数据类型)
- #define MAXMSG 1024
-
- struct msg_st {
- char msg[MAXMSG];
- }__attribute__((packed));
-
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #include <unistd.h>
-
- #include "tcp_proto.h"
- /* 客户端 */
- int main(void)
- {
- int tcp_socket;
- struct sockaddr_in server_addr;
- struct msg_st sndbuf;
- int cnt;
-
- // 创建流式套接字
- tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == tcp_socket) {
- perror("socket()");
- exit(1);
- }
-
- // 请求与服务器连接
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(SERVER_PORT);
- inet_aton(SERVER_IP, &server_addr.sin_addr);
- if (-1 == connect(tcp_socket, (struct sockaddr *)&server_addr, sizeof(server_addr))) {
- perror("connect()");
- goto ERROR;
- }
-
- // 接受
- memset(sndbuf.msg, '\0', MAXMSG);
- strncpy(sndbuf.msg, "this is a test", MAXMSG);
- write(tcp_socket, &sndbuf, MAXMSG);
-
- sleep(2);
-
- close(tcp_socket);
-
- exit(0);
- ERROR:
- close(tcp_socket);
- exit(1);
- }
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <poll.h>
- #include "tcp_proto.h"
- /* 服务端 */
- int main(void)
- {
- int tcp_socket, accepted_socket;
- struct sockaddr_in myaddr;
- pid_t pid;
- struct pollfd *pfd = NULL;
- int nfds = 0;
- struct msg_st rcvbuf;
- int i;
- int cnt;
-
- // 创建流式套接字
- tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == tcp_socket) {
- perror("socket()");
- exit(1);
- }
-
- // 绑定本地地址
- myaddr.sin_family = AF_INET;
- myaddr.sin_port = htons(SERVER_PORT);
- myaddr.sin_addr.s_addr = INADDR_ANY;
- if (-1 == bind(tcp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
- perror("bind()");
- goto ERROR;
- }
-
- // 套接字处于监听状态
- if (-1 == listen(tcp_socket, 200)) {
- perror("listen()");
- goto ERROR;
- }
-
- // 监听tcp_socket
- pfd = calloc(1, sizeof(struct pollfd));
- if (NULL == pfd) {
- perror("calloc()");
- goto ERROR;
- }
- pfd[0].fd = tcp_socket;
- pfd[0].events = POLLIN; // tcp_socket是否有连接
- nfds = 1;
-
- while (1) {
- if (-1 == poll(pfd, nfds, -1)) {
- if (errno == EINTR)
- continue; // 被信号打断
- perror("poll()");
- goto ERROR;
- }
- // 监听的事件发生了
- for (i = 0; i < nfds; i++) {
- if (i == 0) {
- if (pfd[0].fd == tcp_socket && pfd[0].revents & POLLIN) {
- // 套接字有连接到来了
- accepted_socket = accept(tcp_socket, NULL, NULL);
- if (-1 == accepted_socket) {
- perror("accept()");
- goto ERROR;
- }
- printf("**********client connected succefully************\n");
- // accepted_socket 就是将来用于数据交换的套接字
- // 如果可读了再读
- pfd = realloc(pfd, (nfds + 1) * sizeof(struct pollfd));
- // if error
- pfd[nfds].fd = accepted_socket;
- pfd[nfds].events = POLLIN; // 数据
- pfd[nfds].revents = 0;
- nfds ++;
- }
- } else {
- // 不是客户端的连接请求,而是有数据请求
- if (pfd[i].revents & POLLIN) {
- // 创建子进程/线程
- memset(rcvbuf.msg, '\0', MAXMSG);
- cnt = recv(pfd[i].fd, &rcvbuf, MAXMSG, 0);
- if (cnt == -1) {
- perror("recv()");
- goto ERROR;
- }
- if (cnt == 0) {
- // c端close()
- printf("***************888***************\n");
- close(pfd[i].fd);
- pfd[i].events = 0;
- memmove(pfd + i, pfd + i + 1, (nfds - (i + 1)) * sizeof(struct pollfd));
- nfds--;
- pfd = realloc(pfd, nfds * sizeof(struct pollfd));
- i--; // 下一次循环要执行i++
- } else {
- printf("!!!!!!!!!!!recv data!!!!!!!!!!!\n");
- // 接受到数据请求,处理请求
- // 暂且调试输出
- puts(rcvbuf.msg);
- }
- }
- }
- }
- }
-
- close(tcp_socket);
-
- exit(0);
- ERROR:
- close(tcp_socket);
- exit(1);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。