UDP
需要接收才bind
单向
需要双向要绑定两个端口
//int sendto(int sockfd, const void *msg, int len, unsigned int flags,const struct sockaddr *to, int tolen)
//int recvfrom(int sockfd, void *buf, int len, unsigned int flags,struct sockaddr *from, int *fromlen);
//1.文件描述符 2.开关状态 0(不允许接收) 1(不允许发送)
//int shutdown(int sockfd, int how);
/************简单UDP(服务端)********/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/un.h>
#include<sys/ioctl.h>
#include<sys/wait.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define SERVPORT 1234
#define BACKLOG 20
#define MAX_CON_NO 10
#define MAX_DATA_SIZE 1024
int main(int argc, char *argv[]) {
struct sockaddr_in serverSockaddr, clientSockaddr;
int sinSize, recvBytes, sendBytes;
char rBuf[MAX_DATA_SIZE], sBuf[MAX_DATA_SIZE];
pthread_t tid;
int sockfd, clientfd;
int fdmax;
int ret;
int i = 0;
if(argc != 1) {
printf("usage:./server\n");
exit(1);
}
/*establish a socket*/
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("fail to establish a socket");
exit(1);
}
printf("Success to establish a socket...(sockfd = %d)\n", sockfd);
/*init sockaddr_in*/
serverSockaddr.sin_family = AF_INET;
serverSockaddr.sin_port = htons(SERVPORT);
serverSockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(serverSockaddr.sin_zero), 8);
/*bind socket*/
if(bind(sockfd, (struct sockaddr *)&serverSockaddr,
sizeof(struct sockaddr))== -1) {
perror("fail to bind");
exit(1);
}
printf("Success to bind the socket...\n");
while (1)
{
memset(rBuf, 0, sizeof(rBuf));
sinSize = sizeof(struct sockaddr_in);
recvBytes = recvfrom(sockfd, rBuf, sizeof(rBuf), 0,
(struct sockaddr *)&clientSockaddr, &sinSize);
printf("==[%s][%d]", inet_ntoa(clientSockaddr.sin_addr),
ntohs(clientSockaddr.sin_port));
printf("==%s==\n", rBuf);
memset(sBuf, 0, sizeof(sBuf));
gets(sBuf);
sendto(sockfd, sBuf, sizeof(sBuf), 0,
(struct sockaddr *)&clientSockaddr, sizeof(struct sockaddr_in));
}
close(sockfd);
return 0;
}
/*************客户端.c**************/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/un.h>
#include<sys/ioctl.h>
#include<sys/wait.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define SERVPORT 2345
#define BACKLOG 20
#define MAX_CON_NO 10
#define MAX_DATA_SIZE 1024
int main(int argc, char *argv[]) {
struct sockaddr_in serverSockaddr, clientSockaddr;
int sinSize, recvBytes, sendBytes;
char rBuf[MAX_DATA_SIZE], sBuf[MAX_DATA_SIZE];
pthread_t tid;
int sockfd, clientfd;
int fdmax;
int ret;
int i = 0;
if(argc != 1) {
printf("usage:./server\n");
exit(1);
}
/*establish a socket*/
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("fail to establish a socket");
exit(1);
}
printf("Success to establish a socket...(sockfd = %d)\n", sockfd);
/*init sockaddr_in*/
serverSockaddr.sin_family = AF_INET;
serverSockaddr.sin_port = htons(SERVPORT);
serverSockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(serverSockaddr.sin_zero), 8);
/*bind socket*/
if(bind(sockfd, (struct sockaddr *)&serverSockaddr,
sizeof(struct sockaddr))== -1) {
perror("fail to bind");
exit(1);
}
printf("Success to bind the socket...\n");
while (1)
{
memset(sBuf, 0, sizeof(sBuf));
gets(sBuf);
memset(&clientSockaddr, 0, sizeof(struct sockaddr_in));
clientSockaddr.sin_port = htons(1234);
clientSockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sendBytes = sendto(sockfd, sBuf, sizeof(sBuf), 0,
(struct sockaddr *)&clientSockaddr, sizeof(struct sockaddr_in));
memset(rBuf, 0, sizeof(rBuf));
sinSize = sizeof(struct sockaddr_in);
recvBytes = recvfrom(sockfd, rBuf, sizeof(rBuf), 0,
(struct sockaddr *)&clientSockaddr, &sinSize);
printf("==recv:%s==\n", rBuf);
}
close(sockfd);
return 0;
}
IO复用
(实现一个进程监听多个会话客户端)
使用地方:
当一个客户端需要同时处理多个文件描述符的输入输出操作的时候(一般来说是标准的输入输出和网络套接字), I/O 多路复用技术将会有机会得到使用。
当程序需要同时进行多个套接字的操作的时候。
如果一个 TCP 服务器程序同时处理正在侦听网络连接的套接字和已经连接好的套接字。
如果一个服务器程序同时使用 TCP 和UDP 协议。
如果一个服务器同时使用多种服务并且每种服务可能使用不同的协议(比如inetd就是这样的)。
- 基本函数
//1.最大文件描述符+1 2.读子集 3.写子集 4.异常子集(无读写) 5.超时(NULL)
// int select(int numfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
/*********利用select实现定时器功能****/
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <time.h>
int main(int argc, char *argv[])
{
time_t mtime;
struct tm *mytm;
struct stat mystat;
struct timeval tv;
while (1)
{
printf("===select===\n");
memset(&tv, 0, sizeof(struct timeval));
tv.tv_sec = 5;
select(0, NULL, NULL, NULL, &tv);
mtime = time(NULL);
mytm = localtime(&mtime);
printf("==time is %s \n", ctime(&mtime));
}
return 0;
}