codeflysafe Lv5

单进程服务器

code

使用方法

1
./run.sh

客户端 client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

/*
* @Author: sjhuang
* @Date: 2022-03-05 16:35:32
* @LastEditTime: 2022-03-11 12:40:42
* @FilePath: /computer_network/src/socket_c/single_socket_c/client.c
*/
#include "single_socket.h"

int main(){
errno = 0;
char buf[60];
// 创建套接字
int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in serv_addr;
// 客户端也可以调用 bind 来指定端口号,而不是内核随机分配
// 指定端口号,
// struct sockaddr_in cli_addr;
// 初始化 cli_addr
// memset(&cli_addr, 0, sizeof(serv_addr));
// // 指定端口
// cli_addr.sin_port = htons(6666);
// bind(fd, (struct sockaddr *)(&cli_addr), sizeof(cli_addr));

// 初始化 server_addr
memset(&serv_addr, 0, sizeof(serv_addr));
init_serv_addr(&serv_addr);
int n;
pid_t pid = getpid();
// 建立 tcp 连接
int res = connect(fd, (struct sockaddr *)(&serv_addr), sizeof(serv_addr));
if(res < 0){
printf("[client ] connect failed, res: %d, errno: %d\n", res, errno);
}else printf("[client] %d connect successfully !\n", pid);
// 读取从服务器传回的数据
// 阻塞
n = read(fd,buf, sizeof(buf));
if(n > 0) printf("[client] %d, Message received from server: %s\n",pid, buf);
// 关闭套接字
close(fd);
printf("[client] client close: %d\n", getpid());
return 0;
}

server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
* @Author: sjhuang
* @Date: 2022-03-05 16:35:28
* @LastEditTime: 2022-03-11 12:44:02
* @FilePath: /computer_network/src/socket_c/single_socket_c/server.c
*/
#include "single_socket.h"
int main(int argc, char **argv){

// listenfd 监听 fd
// connfd 连接 fd
int listenfd, connfd;
char buff[30];
// 创建套接字,获取 listenfd
listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 常见 sockaddr 结构
struct sockaddr_in serv_addr;
// 填充 0
memset(&serv_addr, 0, sizeof(serv_addr));
init_serv_addr(&serv_addr);
// 监听, 将服务器协议地址赋予给一个套接字
bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
// 监听 listenfd, 将获取的 SYN 的连接放入 SYN_RCVD 队列中
listen(listenfd, BACK_LOG);
// char buf[1024];
// 客户端地址
// int client_num = 0;
struct sockaddr_in cli_addr;
socklen_t addrlen = sizeof(cli_addr);
for(; ;){
errno = 0;
// 从 established 队列中获取连接,
// 如果队列为空,则阻塞此处
connfd = accept(listenfd,(struct sockaddr*)&cli_addr, &addrlen);
if(connfd <= 0){
printf("[Server] connection error : %d",errno);
break;
}
printf("[Server] connection from %s port: %d\n", inet_ntop(AF_INET, &cli_addr.sin_addr,buff, sizeof(buff)),ntohs(cli_addr.sin_port));
char str[] = "hello world!\n";
// 向客户端发送数据
write(connfd,str, sizeof(str));
if(errno != 0){
printf("[Server] connect error: %d\n", errno);
}
// 关闭连接
close(connfd);
}
close(listenfd);
printf("[Server] connect close: %d\n", getpid());
return 0;
}

  • 本文标题:
  • 本文作者:codeflysafe
  • 创建时间:2022-03-18 12:14:00
  • 本文链接:https://codeflysafe.github.io/2022/03/18/单进程服务器/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论