⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp_server.c

📁 采用UDP协议实现的UNIX/Linux环境下的聊天服务器和客户端程序
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <string.h>#include <errno.h>#include "utils.h"#define BUFFER_SIZE	1024int global_recv_buffer_size;int main(int argc, char **argv){  int fd;  if (argc < 3)  {    fprintf(stdout, "Usage: %s <ip> <port>\n", argv[0]);    exit(1);  }  // XXX: step 1, socket();  //int socket(int domain, int type, int protocol);  if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)  {    fprintf(stderr, "Create a new UDP socket failed: %s\n", strerror(errno));    exit(1);  }  socklen_t optlen;  optlen = sizeof(global_recv_buffer_size);  //int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);  if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global_recv_buffer_size, &optlen) < 0)  {    fprintf(stderr, "ERROR: getsockopt() failed: %s\n", strerror(errno));    global_recv_buffer_size = BUFFER_SIZE;  }  fprintf(stdout, "DEBUG: global_recv_buffer_size = %d\n", global_recv_buffer_size);  // XXX: step 2, bind();  struct sockaddr_in server_address;  memset(&server_address, 0, sizeof(server_address));  server_address.sin_family = PF_INET;  server_address.sin_port = htons(atoi(argv[2]));  //server_address.sin_addr.s_addr = inet_addr(argv[1]);  server_address.sin_addr.s_addr = htonl(INADDR_ANY);  // int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);  if (bind(fd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)  {    fprintf(stderr, "ERROR: bind() failed: %s\n", strerror(errno));    // FIXME:    exit(1);  }  char *buffer = NULL;  //char *safe_malloc(int size);  buffer = safe_malloc(global_recv_buffer_size);  for (;;)  {    // XXX: step 3, recvfrom()/sendto    ssize_t n;    struct sockaddr_in peer_address;    socklen_t peer_address_length;    peer_address_length = sizeof(peer_address);  again:    // ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);    if ((n = recvfrom(fd, buffer, global_recv_buffer_size, 0, (struct sockaddr *) &peer_address, &peer_address_length)) < 0)    {      /* These calls return the number of bytes received,        * or -1 if an error occurred.        * The return value will be  0 when the peer has performed an orderly shutdown.       */      if (errno == EINTR)      {	goto again;      }      else      {	fprintf(stderr, "ERROR: recvfrom() failed: %s\n", strerror(errno));      }    }    else    {      fprintf(stdout, "INFO: read %d bytes from %s:%d\n", n, inet_ntoa(peer_address.sin_addr), ntohs(peer_address.sin_port));#if 0      int i;      for (i = 0; i < n; i++)      {	fprintf(stdout, "0x%x", buffer[i]);      }#endif      buffer[n] = '\0';      fprintf(stdout, "DEBUG: %s\n", buffer);      ssize_t sent;    resend:      //ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);      if ((sent = sendto(fd, buffer, n, 0, (struct sockaddr *) &peer_address, sizeof(peer_address))) < 0)      {	if (errno == EINTR)	{	  goto resend;	}	else	{	  fprintf(stdout, "sendto() failed: %s\n", strerror(errno));	}      }      else      {	if (sent < n)	{	  fprintf(stdout, "WARNING: sent message length is less than expected(sent=%d, expected=%d).\n", sent, n);	}      }    }  }  //void safe_free(void *p);  safe_free(buffer);  // XXX: step 4, close()  close(fd);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -