目录
TCP
服务端
多进程
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
perror(msg); \
exit(1); \
}
int main() {
struct sockaddr_in serveraddr, clientaddr;
int listenfd, connfd;
socklen_t clientaddr_len;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int n;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) pexit("socket");
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(SERV_PORT);
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");
if (listen(listenfd, 3) < 0) pexit("listen");
printf("%s\n", "Waiting to be conneted...");
while(1) {
clientaddr_len = sizeof(clientaddr);
connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
if (connfd < 0) pexit("accept");
printf("%s:%d connected\n",
inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)),
ntohs(clientaddr.sin_port)
);
pid_t pid = fork();
if (pid <0) pexit("fork");
if (pid > 0) {
close(connfd);
while(waitpid(-1, NULL, WNOHANG)>0){}
continue;
}
close(listenfd);
while(1) {
n = read(connfd, buf, MAXLINE);
if (!strncmp(buf, "quit", 4)) break;
write(1, buf, n);
for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
write(connfd, buf, n);
}
close(connfd);
printf("%s:%d disconnect\n",
inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)),
ntohs(clientaddr.sin_port)
);
return 0;
}
return 0;
}
多线程
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
perror(msg); \
exit(1); \
}
struct sockaddr_in serveraddr;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
typedef struct ARG{
int connfd;
struct sockaddr_in clientaddr;
}ARG;
void *up_server(void *context) {
pthread_detach(pthread_self());
char str[INET_ADDRSTRLEN];
ARG arg = *((ARG *)context);
int n;
while(1) {
n = read(arg.connfd, buf, MAXLINE);
if (!strncmp(buf, "quit", 4)) break;
write(1, buf, n);
for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
write(arg.connfd, buf, n);
}
close(arg.connfd);
printf("%s:%d disconnect\n",
inet_ntop(AF_INET, &arg.clientaddr.sin_addr, str,sizeof(str)),
ntohs(arg.clientaddr.sin_port)
);
return (void *)0;
}
int main() {
int listenfd, connfd;
socklen_t clientaddr_len;
int n;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) pexit("socket");
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(SERV_PORT);
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");
if (listen(listenfd, 3) < 0) pexit("listen");
printf("%s\n", "Waiting to be conneted...");
struct sockaddr_in clientaddr;
while(1) {
clientaddr_len = sizeof(clientaddr);
connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
if (connfd < 0) pexit("accept");
printf("%s:%d connected\n",
inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)),
ntohs(clientaddr.sin_port)
);
pthread_t tid;
ARG arg = {connfd, clientaddr};
pthread_create(&tid, NULL, up_server, (void *)&arg);
printf("make a new thread: %#lx\n", tid);
}
return 0;
}
线程池
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
perror(msg); \
exit(1); \
}
struct sockaddr_in serveraddr;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
typedef struct Task{
int fd;
struct sockaddr_in clientaddr;
struct Task *next;
} Task;
typedef struct Task_queue {
Task *head;
Task *tail;
pthread_mutex_t lock;
pthread_cond_t havetask;
}Task_queue;
Task_queue *Task_queue_init() {
Task_queue *tq = (Task_queue *)malloc(sizeof(Task_queue));
tq->head = NULL;
tq->tail = NULL;
pthread_mutex_init(&tq->lock, NULL);
pthread_cond_init(&tq->havetask, NULL);
return tq;
}
void Task_queue_push(Task_queue *tq, int fd, struct sockaddr_in clientaddr) {
pthread_mutex_lock(&tq->lock);
Task *t = (Task *)malloc(sizeof(Task));
t->fd = fd;
t->clientaddr = clientaddr;
t->next = NULL;
if (!tq->tail) {
tq->head = tq->tail = t;
} else {
tq->tail->next = t;
tq->tail = t;
}
pthread_cond_broadcast(&tq->havetask);
pthread_mutex_unlock(&tq->lock);
return ;
}
Task Task_queue_pop(Task_queue *tq) {
pthread_mutex_lock(&tq->lock);
while (tq->head == NULL) {
pthread_cond_wait(&tq->havetask, &tq->lock);
}
Task tmp, *k;
k = tq->head;
tmp = *k;
tq->head = tq->head->next;
if (!tq->head) {
tq->tail = NULL;
}
free(k);
pthread_mutex_unlock(&tq->lock);
return tmp;
}
void Task_queue_free(Task_queue *tq) {
pthread_mutex_lock(&tq->lock);
Task *p = tq->head, *k;
while (p) {
k = p;
p = p->next;
free(k);
}
tq->head = tq->tail = NULL;
pthread_mutex_unlock(&tq->lock);
pthread_mutex_destroy(&tq->lock);
pthread_cond_destroy(&tq->havetask);
free(tq);
return ;
}
void *up_server(void *arg) {
pthread_detach(pthread_self());
char str[INET_ADDRSTRLEN];
int n;
Task_queue *tq = arg;
while(1) {
Task tmp = Task_queue_pop(tq);
int connfd = tmp.fd;
while(1) {
n = read(connfd, buf, MAXLINE);
if (!strncmp(buf, "quit", 4)) break;
write(1, buf, n);
for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
write(connfd, buf, n);
}
close(connfd);
printf("%s:%d disconnect\n",
inet_ntop(AF_INET, &tmp.clientaddr.sin_addr, str,sizeof(str)),
ntohs(tmp.clientaddr.sin_port)
);
}
return (void *)0;
}
int main() {
int listenfd, connfd;
socklen_t clientaddr_len;
int n;
Task_queue *tq = Task_queue_init();
pthread_t tid;
for (int i = 0; i < 4; i++) {
pthread_create(&tid, NULL, up_server, (void *)tq);
printf("make a new thread: %#lx\n", tid);
}
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) pexit("socket");
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(SERV_PORT);
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");
if (listen(listenfd, 3) < 0) pexit("listen");
printf("%s\n", "Waiting to be conneted...");
struct sockaddr_in clientaddr;
while(1) {
clientaddr_len = sizeof(clientaddr);
connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
if (connfd < 0) pexit("accept");
printf("%s:%d connected\n",
inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)),
ntohs(clientaddr.sin_port)
);
Task_queue_push(tq, connfd, clientaddr);
}
Task_queue_free(tq);
return 0;
}
epoll+线程池
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<sys/epoll.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 8000
#define pexit(msg) { \
perror(msg); \
exit(1); \
}
struct sockaddr_in serveraddr;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
typedef struct Task{
int fd;
struct sockaddr_in clientaddr;
struct Task *next;
} Task;
typedef struct Task_queue {
Task *head;
Task *tail;
pthread_mutex_t lock;
pthread_cond_t havetask;
}Task_queue;
Task_queue *Task_queue_init() {
Task_queue *tq = (Task_queue *)malloc(sizeof(Task_queue));
tq->head = NULL;
tq->tail = NULL;
pthread_mutex_init(&tq->lock, NULL);
pthread_cond_init(&tq->havetask, NULL);
return tq;
}
void Task_queue_push(Task_queue *tq, int fd, struct sockaddr_in clientaddr) {
pthread_mutex_lock(&tq->lock);
Task *t = (Task *)malloc(sizeof(Task));
t->fd = fd;
t->clientaddr = clientaddr;
t->next = NULL;
if (!tq->tail) {
tq->head = tq->tail = t;
} else {
tq->tail->next = t;
tq->tail = t;
}
pthread_cond_broadcast(&tq->havetask);
pthread_mutex_unlock(&tq->lock);
return ;
}
Task Task_queue_pop(Task_queue *tq) {
pthread_mutex_lock(&tq->lock);
while (tq->head == NULL) {
pthread_cond_wait(&tq->havetask, &tq->lock);
}
Task tmp, *k;
k = tq->head;
tmp = *k;
tq->head = tq->head->next;
if (!tq->head) {
tq->tail = NULL;
}
free(k);
pthread_mutex_unlock(&tq->lock);
return tmp;
}
void Task_queue_free(Task_queue *tq) {
pthread_mutex_lock(&tq->lock);
Task *p = tq->head, *k;
while (p) {
k = p;
p = p->next;
free(k);
}
tq->head = tq->tail = NULL;
pthread_mutex_unlock(&tq->lock);
pthread_mutex_destroy(&tq->lock);
pthread_cond_destroy(&tq->havetask);
free(tq);
return ;
}
void *up_server(void *arg) {
pthread_detach(pthread_self());
char str[INET_ADDRSTRLEN];
int n;
Task_queue *tq = arg;
while(1) {
Task tmp = Task_queue_pop(tq);
int connfd = tmp.fd;
n = read(connfd, buf, MAXLINE);
write(1, buf, n);
if (!strncmp(buf, "quit", 4)) {
close(connfd);
printf("%s:%d disconnect\n",
inet_ntop(AF_INET, &tmp.clientaddr.sin_addr, str,sizeof(str)),
ntohs(tmp.clientaddr.sin_port)
);
} else {
for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
write(connfd, buf, n);
}
}
return (void *)0;
}
int main() {
int listenfd, connfd;
socklen_t clientaddr_len;
int n;
Task_queue *tq = Task_queue_init();
pthread_t tid;
for (int i = 0; i < 4; i++) {
pthread_create(&tid, NULL, up_server, (void *)tq);
printf("make a new thread: %#lx\n", tid);
}
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) pexit("socket");
int epfd = epoll_create(256);
struct epoll_event ev, events[256];
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listenfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(SERV_PORT);
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");
if (listen(listenfd, 3) < 0) pexit("listen");
printf("%s\n", "Waiting to be conneted...");
struct sockaddr_in clientaddr;
while(1) {
int nfds = epoll_wait(epfd, events, 256, -1);
for (int i = 0; i < nfds; i++) {
if(events[i].data.fd == listenfd) {
clientaddr_len = sizeof(clientaddr);
connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
if (connfd < 0) pexit("accept");
printf("%s:%d connected\n",
inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)),
ntohs(clientaddr.sin_port)
);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = connfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
} else if (events[i].events & EPOLLIN) {
int clientfd = events[i].data.fd;
if (clientfd < 3) continue;
getpeername(clientfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
Task_queue_push(tq, clientfd, clientaddr);
}
}
}
Task_queue_free(tq);
return 0;
}
客户端
#include<stdio.h>
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<string.h>
#define SERV_PORT 9000
#define MAXLINE 80
int main() {
struct sockaddr_in serveraddr;
char buf[MAXLINE] = {"hello\n"};
int connfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(SERV_PORT);
inet_pton(AF_INET, "127.0.0.1", &serveraddr.sin_addr);
connect(connfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
int n;
while (n=read(0, buf, MAXLINE)) {
write(connfd, buf, n);
if (!strncmp(buf, "quit", 4)) break;
int n = read(connfd, buf, MAXLINE);
printf("response from server:\n");
write(1, buf, n);
}
close(connfd);
return 0;
}
UDP
服务端
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
perror(msg); \
exit(1); \
}
int main() {
int sockfd;
struct sockaddr_in serveraddr, clientaddr;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
socklen_t clientaddr_len;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(SERV_PORT);
bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
printf("Wating to receive data...\n");
int n;
while(1) {
n = recvfrom(sockfd, buf, MAXLINE, 0, (struct sockaddr *)&clientaddr, &clientaddr_len);
if (n < 0) pexit("recvfrom");
printf("received from %s:%d\n",
inet_ntop(AF_INET, &clientaddr.sin_addr, str, sizeof(str)),
ntohs(clientaddr.sin_port));
write(1, buf, n);
for (int i = 0; i < n; i++) buf[i] = toupper(buf[i]);
sendto(sockfd, buf, n, 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
}
close(sockfd);
return 0;
}
客户端
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
perror(msg); \
exit(1); \
}
int main() {
struct sockaddr_in serveraddr;
int sockfd;
int n;
char buf[MAXLINE] = "hello\n";
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, "127.0.0.1", &serveraddr.sin_addr);
if (sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("sendto");
while(n = read(0, buf, MAXLINE)) {
n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
write(1, buf, n);
}
close(sockfd);
return 0;
}