1.1 理解网络编程 和 套接字
2025/9/9大约 2 分钟
1.1 理解网络编程 和 套接字
[!quote]
网络编程就是编写程序使两台连网的计算机相互交换数据。
- 网络连接
- 操作系统提供数据传输用的软件接口 - socket
使用socket 进行网络通讯 和 电话机的类比
| 接口(省略参数) | 功能 | 电话机 |
|---|---|---|
| socket | 创建socket | 购买 |
| bind | 分配地址信息 | 分配号码 |
| listen | 监听 | 连接电话线 |
| accept | 接收连接请求 | 接听 |
| connect | 发送连接请求 | 拨打电话 |
| 区别于电话机的是,电话机同时具备拨打电话 和 接听电话的功能(不能在拨打电话的同时接听来电),但是socket 调用listen 后即进入监听状态,只能接收连接请求,不能再connect。同样地,socket 调用connect 成功后 不能再入监听状态。 |
"Hello World" 服务端
在linux 运行服务端,使用网络调试工具连接服务端。
实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(int argc, char* argv[])
{
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr, clnt_addr;
socklen_t clnt_addr_size;
char message[] = "Hello World!";
if(argc != 2)
{
printf("Usage : %s <port> \n", argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
error_handling("serv_socket() error");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1)
error_handling("bind() error");
if(listen(serv_sock, 5) == -1)
error_handling ("listen() error");
clnt_addr_size = sizeof(clnt_addr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
if(clnt_sock == -1)
error_handling ("accept() error");
write(clnt_sock , message, sizeof(message));
close(clnt_sock );
close(serv_sock );
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}效果:
启动程序:Network 10086
服务端地址为192.168.56.101
配置客户端地址为 192.168.56.1
连接后收到服务端消息:
RECV ASCII/13 from SERVER <<<
Hello World!"Hello World" 客户端
实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <errno.h>
void error_handling(char *message);
int main(int argc, char* argv[])
{
int sock;
struct sockaddr_in serv_addr;
char message[30];
int str_len;
if(argc != 3)
{
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1)
error_handling("serv_socket() error");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
serv_addr.sin_port = htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
{
error_handling("connect() error!");
}
str_len = read(sock, message, sizeof(message) - 1);
if(str_len == -1)
error_handling("read() error!");
printf("Message from server :%s\n", message);
close(sock );
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fprintf(stderr, " %s", strerror(errno));
fputc('\n', stderr);
exit(1);
}效果:
网络调试工具建立server,启动client 后 server发送数据,client 能够接收并打印
Message from server :Hello Client