// #include <sys/socket.h> ssize_t sendmsg(int socket, const struct msghdr *message, int flags); ssize_t sendto(int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
发送数据时要指定接收方的地址。
// #include <sys/socket.h> ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len); ssize_t recvmsg(int socket, struct msghdr *message, int flags);
接收数据时,会获取到发送方的地址。
common.h
#ifndef COMMON_H #define COMMON_H #include <sys/types.h> #include <sys/socket.h> #include <sys/uio.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> extern const char *g_srvIp; extern uint16_t g_srvPort; extern uint32_t g_backLog; extern int RET_OK; extern int RET_ERR; extern const uint32_t MESSAGE_SIZE; extern const uint32_t BUF_SIZE; extern void PrintTime(); #endif
common.c
#include "common.h" const char *g_srvIp = "127.0.0.1"; uint16_t g_srvPort = 1234; uint32_t g_backLog = 1024; int RET_OK = 0; int RET_ERR = -1; const uint32_t MESSAGE_SIZE = 10240; const uint32_t BUF_SIZE = 1024; void PrintTime() { time_t rawTime; time(&rawTime); fprintf(stdout, "%ld\n", rawTime); }
Makefile
CC = gcc CFLAGS = -g -std=c11 COMMON = ../lib/common.c INC = -I ../ # 头文件查找路径 server : server.c $(COMMON) $(CC) $(CFLAGS) server.c $(COMMON) $(INC) -o server client : client.c $(COMMON) $(CC) $(CFLAGS) client.c $(COMMON) $(INC) -o client clean : rm client server
server.c
#include "lib/common.h" static int g_count = 0; static void SignalInterruptFunc(int signo) { printf("\n%d datagrams received\n", g_count); exit(0); } static int MakeSrvAddr(int socketFd) { struct sockaddr_in srvAddr; bzero(&srvAddr, sizeof(srvAddr)); srvAddr.sin_family = AF_INET; srvAddr.sin_addr.s_addr = htonl(INADDR_ANY); srvAddr.sin_port = htons(g_srvPort); if (bind(socketFd, (struct sockaddr *)&srvAddr, sizeof(srvAddr)) == -1) { perror("bind"); return RET_ERR; } return RET_OK; } int main() { int socketFd = socket(AF_INET, SOCK_DGRAM, 0); if (socketFd == -1) { perror("socket"); return RET_ERR; } if (MakeSrvAddr(socketFd) == RET_ERR) { perror("MakeSrvAddr"); return RET_ERR; } signal(SIGINT, SignalInterruptFunc); struct sockaddr_in cliAddr; socklen_t cliLen = 110; char message[BUF_SIZE]; for (;;) { fprintf(stdout, "wait receive ...\n"); int n = recvfrom(socketFd, message, BUF_SIZE, 0, (struct sockaddr *)&cliAddr, &cliLen); if (n == -1) { perror("recvfrom"); break; } ++g_count; message[n] = '\0'; fprintf(stdout, "%d bytes received\n", n); fprintf(stdout, "start send ...\n"); n = sendto(socketFd, message, strlen(message), 0, (struct sockaddr *)&cliAddr, cliLen); if (n == -1) { perror("sendto"); break; } fprintf(stdout, "%d bytes sent\n", n); } return 0; }
client.c
#include "lib/common.h" static int g_count = 0; static void SignalInterruptFunc(int signo) { printf("\n%d datagrams sent\n", g_count); exit(0); } int main() { int socketFd = socket(AF_INET, SOCK_DGRAM, 0); if (socketFd == -1) { perror("socket"); return RET_ERR; } struct sockaddr_in srvAddr; bzero(&srvAddr, sizeof(srvAddr)); srvAddr.sin_family = AF_INET; srvAddr.sin_port = htons(g_srvPort); if (inet_pton(AF_INET, g_srvIp, &srvAddr.sin_addr) != 1) { perror("inet_pton"); return RET_ERR; } signal(SIGINT, SignalInterruptFunc); char send[BUF_SIZE]; for (int i = 0; i < BUF_SIZE; ++i) { send[i] = 'a'; } send[BUF_SIZE] = '\0'; socklen_t srvLen = sizeof(srvAddr); for (;;) { fprintf(stdout, "start send ...\n"); int n = sendto(socketFd, send, strlen(send), 0, (struct sockaddr *)&srvAddr, srvLen); if (n == -1) { perror("sendto"); break; } ++g_count; fprintf(stdout, "%d bytes sent\n", n); char recv[BUF_SIZE]; fprintf(stdout, "wait receive ...\n"); n = recvfrom(socketFd, recv, BUF_SIZE, 0, (struct sockaddr *)&srvAddr, &srvLen); if (n == -1) { perror("recvfrom"); break; } fprintf(stdout, "%d received\n", n); } return 0; }
两端之间互相发送报文。