UDP客户端使用connect与UDP服务器使用send函数和recv函数收发数据
服务器代码编译运行
服务器udpconnectToServer.c
的代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<errno.h>
#include<syslog.h>
#include<signal.h>
#define MAXLINE 4096
static int count;
static void quitHere(int signo) {
printf("\nreceived %d datagrams\n", count);
exit(0);
}
int main(int argc, char **argv) {
int socket_fd;
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));
bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));
socklen_t client_len;
char message[MAXLINE];
message[0] = 0;
count = 0;
signal(SIGINT, quitHere);
struct sockaddr_in client_addr;
client_len = sizeof(client_addr);
// recvfrom会把客户端返回对端发送方的地址和端口等信息放到client_addr和client_len中
int n = recvfrom(socket_fd, message, MAXLINE, 0, (struct sockaddr *) &client_addr, &client_len);
if (n < 0) {
fprintf(stderr, "error in recvfrom function: %s (%d)\n", strerror(errno), errno);
}
message[n] = 0;
printf("received length is %d bytes \ncontent: %s\n", n, message);
if (connect(socket_fd, (struct sockaddr *) &client_addr, client_len)) {
fprintf(stderr, "connect error: %s (%d)\n", strerror(errno), errno);
}
while (strncmp(message, "quit", 4) != 0) {
char send_line[MAXLINE];
sprintf(send_line, "Hi, %s", message);
size_t rt = send(socket_fd, send_line, strlen(send_line), 0);
if (rt < 0) {
fprintf(stderr, "send error: %s (%d)\n", strerror(errno), errno);
}
printf("send bytes: %zu \n", rt);
size_t rc = recv(socket_fd, message, MAXLINE, 0);
if (rc < 0) {
fprintf(stderr, "recv error: %s (%d)\n", strerror(errno), errno);
}
count++;
}
exit(0);
}
gcc udpconnectserver.c -o udpconnectserver
进行编译,./udpconnectserver 8080
运行。
客户端代码编译与运行
客户端udpconnectToServer.c
的代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<errno.h>
#include<syslog.h>
# define MAXNUMBER 4096
int main(int argc, char **argv) {
if (argc != 3) {
printf("usage: udpclient1 <IPaddress> or <Port>");
}
int socket_fd;
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
socklen_t server_len = sizeof(server_addr);
if (connect(socket_fd, (struct sockaddr *) &server_addr, server_len)) {
printf("fail in connect");
exit(1);
}
struct sockaddr *reply_addr;
reply_addr = malloc(server_len);
char sendLine[MAXNUMBER], receiveLine[MAXNUMBER + 1];
socklen_t len;
int n;
while (fgets(sendLine, MAXNUMBER, stdin) != NULL) {
int i = strlen(sendLine);
if (sendLine[i - 1] == '\n') {
sendLine[i - 1] = 0;
}
printf("send Content: %s\n", sendLine);
size_t rt = send(socket_fd, sendLine, strlen(sendLine), 0);
if (rt < 0) {
printf("error in sending");
}
printf("send Content's bytes: %zu \n", rt);
len = 0;
receiveLine[0] = 0;
n = recv(socket_fd, receiveLine, MAXNUMBER, 0);
if (n < 0){
if (errno){
fprintf(stderr, "error in recvfrom: %s (%d)\n", strerror(errno), errno);
}else{
printf("recvfrom not success");
}
}
receiveLine[n] = 0;
fputs(receiveLine, stdout);
fputs("\n", stdout);
}
exit(0);
}
gcc udpconnectToServer.c -o udpconnectToServer
进行编译,./udpconnectToServer 127.0.0.1 8080
运行。
实验
这里打开两个终端,然后连接到同一个机器上边。
然后在客户端发送一条信息good
,可以看到服务器上收到了good
并且给客户端发送了Hi, good
。
以quit
开头的字符串从客户端发送过来之后,就会让服务器关闭。
此文章为11月Day 23学习笔记,内容来源于极客时间《网络编程实战》。