6.4 TCP编程简单示例
服务器首先进行初始化操作:调用函数socket创建一个套接字,函数bind将这个套接字与服务器的公认地址绑定在一起,函数listen将这个套接字换成倾听套接字,然后调用函数accept来等待客户机的请求。过了一段时间后,客户机启动,调用socket创建一个套接字,然后调用函数connect来与服务器建立连接。连接建立之后,客户机和服务器通过读、写套接字来进行通信。
6.4.1 服务器端代码
参考:TCP/server_line.c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <netinet/in.h>
7#include <arpa/inet.h>
8#include <unistd.h>
9#include <signal.h>
10
11#define SERVER_PORT 8180
12#define C_QUEUE 10
13
14
22
23int main(int argc, char **argv)
24{
25 char buf[512];
26 int len;
27 int duty_socket;
28 int customer_socket;
29 struct sockaddr_in socket_server_addr;
30 struct sockaddr_in socket_client_addr;
31 int ret;
32 int addr_len;
33
34 signal(SIGCHLD, SIG_IGN);
35
36
37 duty_socket = socket(AF_INET, SOCK_STREAM, 0);
38 if (duty_socket == -1)
39 {
40 printf("socket error");
41 return -1;
42 }
43
44
45 socket_server_addr.sin_family = AF_INET;
46
47 socket_server_addr.sin_port = htons(SERVER_PORT);
48
49 socket_server_addr.sin_addr.s_addr = INADDR_ANY;
50 memset(socket_server_addr.sin_zero, 0, 8);
51
52
53 ret = bind(duty_socket, (const struct sockaddr *)&socket_server_addr, sizeof(struct sockaddr));
54 if (ret == -1)
55 {
56 printf("bind error!\n");
57 return -1;
58 }
59 ret = listen(duty_socket, C_QUEUE);
60 if (ret == -1)
61 {
62 printf("listen error!\n");
63 return -1;
64 }
65
66 while (1)
67 {
68 addr_len = sizeof(struct sockaddr);
69
70 customer_socket = accept(duty_socket, (struct sockaddr *)&socket_client_addr, &addr_len);
71 if (customer_socket != -1)
72 {
73
74 printf("Get connect from %s\n", inet_ntoa(socket_client_addr.sin_addr));
75 }
76 if (!fork())
77 {
78 while (1)
79 {
80 memset(buf, 512, 0);
81
82 len = recv(customer_socket, buf, sizeof(buf), 0);
83 buf[len] = '\0';
84 if (len <= 0)
85 {
86 close(customer_socket);
87 return -1;
88 }
89 else
90 {
91 printf("Get connect from %s, Msg is %s\n", inet_ntoa(socket_client_addr.sin_addr), buf);
92 }
93 }
94 }
95 }
96
97 close(duty_socket);
98 return 0;
99}
6.4.2 客户端代码
参考:TCP/client_line.c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <netinet/in.h>
7#include <arpa/inet.h>
8#include <unistd.h>
9
10#define SERVER_PORT 8180
11
19
20int main(int argc, char **argv)
21{
22 unsigned char buf[512];
23 int len;
24 struct sockaddr_in socket_server_addr;
25 int ret;
26 int addr_len;
27 int client_socket;
28
29
30 if (argc != 2)
31 {
32 printf("Usage:\n");
33 printf("%s <server_ip>\n", argv[0]);
34 return -1;
35 }
36
37
38 client_socket = socket(AF_INET, SOCK_STREAM, 0);
39 if (client_socket == -1)
40 {
41 printf("socket error");
42 return -1;
43 }
44
45
46 socket_server_addr.sin_family = AF_INET;
47
48 socket_server_addr.sin_port = htons(SERVER_PORT);
49 if (inet_aton(argv[1], &socket_server_addr.sin_addr) == 0)
50 {
51 printf("invalid server ip\n");
52 return -1;
53 }
54 memset(socket_server_addr.sin_zero, 0, 8);
55
56 ret = connect(client_socket, (const struct sockaddr *)&socket_server_addr, sizeof(struct sockaddr));
57 if (ret == -1)
58 {
59 printf("connect error!\n");
60 return -1;
61 }
62
63
64 while (1)
65 {
66 if (fgets(buf, sizeof(buf), stdin))
67 {
68 len = send(client_socket, buf, strlen(buf), 0);
69 if (len <= 0)
70 {
71 close(client_socket);
72 return -1;
73 }
74 }
75 }
76
77 close(client_socket);
78 return 0;
79}
6.4.3 Makefile文件
all:server client
server:server.c
gcc $^ -o $@
client:client.c
gcc $^ -o $@
clean:
rm server client -f
(注意:命令语句的开头要用“Tab”键。)
6.4.4 执行
服务器端:
./server
客户端:
./client 127.0.0.1
客户端输入:
good night
服务器端显示:
Get connect from 127.0.0.1
Get connect from 127.0.0.1, Msg is good night