多进程
server.c
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PRINT_ERR(msg) \
do { \
printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
perror(msg); \
exit(-1); \
} while (0)
int main(int argc, const char * argv[]) {
if (argc != 3) {
printf("Usage: %s <IP> <port>\n", argv[0]);
exit(-1);
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
PRINT_ERR("socket error");
}
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt));
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
socklen_t serveraddr_len = sizeof(serveraddr);
if (bind(sockfd, (struct sockaddr*)&serveraddr, serveraddr_len) == -1) {
PRINT_ERR("bind error");
}
if (listen(sockfd, 5) == -1) {
PRINT_ERR("listen error");
}
struct sockaddr_in client_addr;
memset(&client_addr, 0, sizeof(client_addr));
socklen_t clientaddr_len = sizeof(client_addr);
int acceptfd = 0;
while (1) {
if ((acceptfd = accept(sockfd, (struct sockaddr *)&client_addr, &clientaddr_len)) == -1) {
PRINT_ERR("accept error");
}
printf("client [%s:%d] connect!!!..\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
pid_t pid = fork();
if (pid == 0) {
while (1) {
char buf[128];
int nbytes = 0;
memset(buf, 0 , sizeof(buf));
if(-1 == (nbytes = recv(acceptfd, buf, sizeof(buf), 0))){
PRINT_ERR("recv error");
} else if(0 == nbytes){
printf("client[%s:%d] disconnect!!!..\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
break;
}
printf("receive data [%s]\n", buf);
if (!strncmp(buf, "quit", 4)) {
break;
}
strcat(buf, "---hi!!!");
write(acceptfd, buf, sizeof(buf));
}
close(acceptfd);
}
close(acceptfd);
}
return 0;
}
多线程
server.c
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PRINT_ERR(msg) \
do { \
printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
perror(msg); \
exit(-1); \
} while (0)
void *task(void *argv) {
int acceptfd = *((int *)argv);
while (1) {
char buf[128];
int nbytes = 0;
memset(buf, 0 , sizeof(buf));
if(-1 == (nbytes = recv(acceptfd, buf, sizeof(buf), 0))){
PRINT_ERR("recv error");
} else if(0 == nbytes){
printf("disconnect!!!..\n");
break;
}
printf("receive data [%s]\n", buf);
if (!strncmp(buf, "quit", 4)) {
break;
}
strcat(buf, "---hi!!!");
write(acceptfd, buf, sizeof(buf));
}
close(acceptfd);
return NULL;
}
int main(int argc, const char * argv[]) {
if (argc != 3) {
printf("Usage: %s <IP> <port>\n", argv[0]);
exit(-1);
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
PRINT_ERR("socket error");
}
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt));
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
socklen_t serveraddr_len = sizeof(serveraddr);
if (bind(sockfd, (struct sockaddr*)&serveraddr, serveraddr_len) == -1) {
PRINT_ERR("bind error");
}
if (listen(sockfd, 5) == -1) {
PRINT_ERR("listen error");
}
struct sockaddr_in client_addr;
memset(&client_addr, 0, sizeof(client_addr));
socklen_t clientaddr_len = sizeof(client_addr);
int acceptfd = 0;
while (1) {
if ((acceptfd = accept(sockfd, (struct sockaddr *)&client_addr, &clientaddr_len)) == -1) {
PRINT_ERR("accept error");
}
printf("client [%s:%d] connect!!!..\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
pthread_t pid;
pthread_create(&pid, NULL, task, &acceptfd);
pthread_detach(pid);
}
return 0;
}
client.c
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PRINT_ERR(msg) \
do { \
printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
perror(msg); \
exit(-1); \
} while (0)
int main(int argc, const char *argv[]) {
if (argc != 3) {
printf("Usage: %s <IP> <port>\n", argv[0]);
exit(-1);
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
PRINT_ERR("sock error");
}
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
socklen_t serveraddr_len = sizeof(serveraddr);
if (connect(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len) == -1) {
PRINT_ERR("connect error");
}
printf("connect success!!!\n");
char buf[128] = {0};
while (1) {
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
send(sockfd, buf, sizeof(buf), 0);
if (!strncmp(buf, "quit", 4)) {
break;
}
memset(buf, 0, sizeof(buf));
recv(sockfd, buf, sizeof(buf), 0);
printf("receive--->[%s]\n", buf);
}
close(sockfd);
return 0;
}
执行代码
server
ubuntu@ubuntu $ ./server 127.0.0.1 8888
client [127.0.0.1:47470] connect!!!..
client [127.0.0.1:47484] connect!!!..
receive data [1]
receive data [2]
receive data [3]
receive data [1]
receive data [quit]
receive data [quit]
^C
ubuntu@ubuntu $
client1
ubuntu@ubuntu $ ./client 127.0.0.1 8888
connect success!!!
2
receive--->[2---hi!!!]
3
receive--->[3---hi!!!]
1
receive--->[1---hi!!!]
quit
ubuntu@ubuntu $
client2
ubuntu@ubuntu $ ./client 127.0.0.1 8888
connect success!!!
1
receive--->[1---hi!!!]
quit
ubuntu@ubuntu $