TCP服务器
server.c的作用是接受client的请求,并与client进行简单的数据通信
2 #include <stdio.h>
3 #include <sys/socket.h>
4 #include <netinet/in.h>
5 #include <errno.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <sys/types.h>
9
10 #define _PORT_ 9999
11 #define _BACKLOG_ 10
12
13 int main()
14 {
15 int sock = socket(AF_INET, SOCK_STREAM, 0); //SOCK_STREAM表示面向流的传输协议,即TCP协议
16 if(sock < 0){
17 printf("create socket error, errno is: %d, errstring is: %s\n", errno,strerror(errno));
18 }
19
20 struct sockaddr_in server_socket;
21 struct sockaddr_in client_socket;
22 bzero(&server_socket, sizeof(server_socket)); //将整个结构体清零
23 server_socket.sin_family = AF_INET;
24 server_socket.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY是一个宏,表示本地的任意IP地址
25 server_socket.sin_port = htons(_PORT_);
26
27 if(bind(sock, (struct sockaddr*)&server_socket, sizeof(struct sockaddr_in)) < 0){
28 printf("bind error,error code is: %d, error string: %s\n", errno, strerror(errno));
29 close(sock);
return 1;
31 }
32
33 if(listen(sock, _BACKLOG_) < 0){
34 printf("listen error, error code: %d, error string is : %s\n", errno, strerror(errno));
35 close(sock);
36 return 2;
37 }
38
39 printf("bind and listen success, wait accept...\n");
40
41 for(;;){
42 socklen_t len = 0;
43 int client_sock = accept(sock, (struct sockaddr*)&client_socket, &len);
44 if( client_sock < 0 ){
45 printf("accept error, errno is: %d, err string is: %s\n", errno, strerror(errno));
46 close(sock);
47 return 3;
48 }
49
50 char buf_ip[INET_ADDRSTRLEN];
51 memset(buf_ip, '\0', sizeof(buf_ip));
52 inet_ntop(AF_INET, &client_socket.sin_addr, buf_ip, sizeof(buf_ip));
53 printf("get connect, ip is: %s port is: %s\n", buf_ip, ntohs(client_socket.sin_port));
55
56 while(1){
57 char buf[1024];
58 memset(buf, '\0', sizeof(buf));
59
60 read(client_sock, buf, sizeof(buf));
61 printf("client:# %s\n",buf);
62
63 printf("server : $ ");
64
65 memset(buf, '\0', sizeof(buf));
66 fgets(buf, sizeof(buf), stdin);
67 buf[strlen(buf)-1] = '\0';
68 write(client_sock, buf, strlen(buf)-1);
69 printf("please wait...\n");
70 }
71 }
72 close(sock);
73 return 0;
74 }
TCP客户端
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <sys/socket.h>
6 #include <sys/types.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <string.h>
10 #include <errno.h>
11
12 #define SERVER_PORT 9999
13 #define SERVER_IP "192.168.0.111"
14
15
16 int main(int argc, char* argv[])
17 {
18 if(argc != 2){
19 printf("Usage:client IP\n");
20 }
21 char *str = argv[1];
22 char buf[1024];
23
24 struct sockaddr_in server_sock;
25 int sock = socket(AF_INET, SOCK_STREAM, 0);
26 bzero(&server_sock, sizeof(server_sock));
27 server_sock.sin_family = AF_INET;
28 inet_pton(AF_INET, SERVER_IP, &server_sock.sin_addr); //将点分十进制转换成32位的IP 地址
30 int ret = connect(sock, (struct sockaddr*)&server_sock, sizeof(server_sock));
31 if(ret < 0){
32 perror("connect");
33 return;
34 }
35 printf("connect success...\n");
36
37 while(1){
38 printf("clinet: # ");
39 fgets(buf, sizeof(buf), stdin);
40 buf[strlen(buf)-1] = '\0';
41 write(sock, buf, sizeof(buf));
42 if(strncasecmp(buf, "quit", 4) == 0){
43 printf("quit\n");
44 break;
45 }
46 printf("please wait...\n");
47 read(sock, buf, sizeof(buf));
48 printf("server: $ %s\n", buf);
49 }
50
51 close(sock);
52
53 return 0;
54 }
参数说明:
1.. 将整个结构体清零;
2. 设置地址类型为AF_INET;
3. 网络地址为INADDR_ANY, 这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也 可能绑定多个IP 地址, 这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定 下来到底用哪个IP 地址;
4. 端⼝口号为SERV_PORT, 我们定义为9999
上述的客户端/服务器·只能处理一个连接,下面是多进程版本的
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/socket.h>
5 #include <sys/types.h>
6 #include <netinet/in.h>
7 #include <arpa/inet.h>
8 #include <sys/wait.h>
9 #include <string.h>
10 #include <unistd.h>
11
12
13 void ProcessRequest(int client_fd, struct sockaddr_in *client_addr)
14 {
15 char buf[1024];
16 for(;;){
17 ssize_t read_size = read(client_fd, buf, sizeof(buf));
18 if(read_size < 0){
19 perror("read");
20 continue;
21 }
22 if( read_size == 0 ){
23 printf("client: %s say bye!\n", inet_ntoa(client_addr->sin_addr));
24 close(client_fd);
25 break;
26 }
27 buf[read_size] = '\0';
28 printf("client %s say:%s!\n", inet_ntoa(client_addr->sin_addr), buf);
29 write(client_fd, buf, strlen(buf));
}
31 return;
32 }
33
34 void CreateWorker(int client_fd, struct sockaddr_in *client_addr)
35 {
36 pid_t pid = fork();
37 if( pid < 0 ){
38 perror("fork");
39 return;
40 }else if( pid == 0 ){
41 //child
42 if( fork() == 0 ){
43 //孙子进程
44 ProcessRequest(client_fd, client_addr);
45 }
46 exit(0);
47 }else{
48 //father
49 close(client_fd);
50 waitpid(pid, NULL, 0);
51 }
52
53 }
54
55
56 void Usage()
57 {
58 printf("Usage: ./server [ip] [port] \n");
59 }
60
61
62 int main(int argc ,char *argv[])
63 {
64 if( argc != 3 ){
65 Usage();
66 return 1;
67 }
68
69 struct sockaddr_in addr;
70 addr.sin_family = AF_INET;
71 addr.sin_port = htons(atoi(argv[2]));
72 addr.sin_addr.s_addr = inet_addr(argv[1]);
73
74 int fd = socket(AF_INET, SOCK_STREAM, 0);
75 if(fd < 0){
76 perror("socket");
77 return 2;
78 }
79
80 int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
81 if( ret < 0 ){
82 perror("bind");
83 return 3;
84 }
85
86 ret = listen(fd, 10);
87 if( ret < 0 ){
88 perror("listen");
89 return 4;
90 }
91
92 for(;;){
93 struct sockaddr_in client_addr;
94 socklen_t len = sizeof(client_addr);
95 int client_fd = accept(fd, (struct sockaddr*)&client_addr, &len);
96 if( client_fd < 0 ){
97 perror("accept");
98 continue;
99 }
100 CreateWorker(client_fd, &client_addr);
101
102 }
103 return 0;
104 }
多线程版本
2 #include <pthread.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/socket.h>
6 #include <sys/types.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <sys/wait.h>
10 #include <string.h>
11 #include <unistd.h>
12
13
14 void ProcessRequest(int client_fd, struct sockaddr_in *client_addr)
15 {
16 char buf[1024];
17 for(;;){
18 ssize_t read_size = read(client_fd, buf, sizeof(buf));
19 if(read_size < 0){
20 perror("read");
21 continue;
22 }
23 if( read_size == 0 ){
24 printf("client: %s say bye!\n", inet_ntoa(client_addr->sin_addr));
25 close(client_fd);
26 break;
27 }
28 buf[read_size] = '\0';
29 printf("client %s say:%s!\n", inet_ntoa(client_addr->sin_addr), buf);
30 write(client_fd, buf, strlen(buf));
31 }
32 }
33
34 typedef struct Arg{
35 int fd;
36 struct sockaddr_in addr;
37 }Arg;
38
39 void CreateWorker(void *ptr)
40 {
41 Arg *arg = (Arg*)ptr;
42 ProcessRequest(arg->fd, &arg->addr);
43 free(arg);
44 return NULL;
45 }
46
47 void Usage()
48 {
49 printf("Usage: ./server [ip] [port] \n");
50 }
51
52
53 int main(int argc ,char *argv[])
54 {
55 if( argc != 3 ){
56 Usage();
57 return 1;
58 }
59
60 struct sockaddr_in addr;
61 addr.sin_family = AF_INET;
62 addr.sin_port = htons(atoi(argv[2]));
63 addr.sin_addr.s_addr = inet_addr(argv[1]);
64
65 int fd = socket(AF_INET, SOCK_STREAM, 0);
66 if(fd < 0){
67 perror("socket");
68 return 2;
69 }
70
71 int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
72 if( ret < 0 ){
73 perror("bind");
74 return 3;
75 }
76
77 ret = listen(fd, 10);
78 if( ret < 0 ){
79 perror("listen");
80 return 4;
81 }
82
83 for(;;){
84 struct sockaddr_in client_addr;
85 socklen_t len = sizeof(client_addr);
86 int client_fd = accept(fd, (struct sockaddr*)&client_addr, &len);
87 if( client_fd < 0 ){
88 perror("accept");
89 continue;
90 }
91 pthread_t tid = 0;
92 Arg *arg = (Arg*)malloc(sizeof(Arg));
93 arg->fd = client_fd;
94 arg->addr = client_addr;;
95 pthread_create(&tid, NULL, CreateWorker, (void*)arg);
96 pthread_detach(tid);
97
98 }
99 return 0;
100 }