网络通信
Socket通信的3要素
- 通信的目的地址
- 使用的端口号
- 使用的传输层协议(如TCP、UDP)
Socket通信模型
简单的回声服务器实现
服务端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#define SERVER_PORT 666
int main(void){
int sock;//信箱
struct sockaddr_in server_addr;
//创建信箱
sock = socket(AF_INET,SOCK_STREAM,0);
//清空标签
bzero(&server_addr,sizeof(server_addr));
//写上地址和端口号
server_addr.sin_family = AF_INET; //选择协议族ipv4
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//监听本地所有IP地址-几个网卡就有几个IP地址
server_addr.sin_port = htons(SERVER_PORT); //绑定端口号
//实现标签贴到收信的信箱上
bind(sock,(struct sockaddr*)&server_addr,sizeof(server_addr));
//邮箱一次性只能接收128封信件
listen(sock,128);
printf("等待客户端链接\n");
int done = 1;
while(done){
struct sockaddr_in client;
int client_socket;
int len;
char client_ip[64];
char buf[256];
socklen_t client_addr_len;
client_addr_len = sizeof(client);
client_socket = accept(sock,(struct sockaddr*)&client,&client_addr_len);
printf("客户端地址:%s\t端口:%d\n",inet_ntop(AF_INET,&client.sin_addr.s_addr,client_ip,sizeof(client_ip)),ntohs(client.sin_port));
//读取数据
len = read(client_socket,buf,sizeof(buf)-1);
buf[len] = '\n';//read读过来的数据不会自动加字符串结束符
printf("收到[%d]:%s\n",len,buf);
len = write(client_socket,buf,len);//发回去
printf("写完,len:%d",len);
close(client_socket);
}
return 0;
}
可以使用telnet来模拟客户端链接服务器。例如:
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 666
#define SERVER_IP "127.0.0.1"
int main(int argc, char* argv[]) {
int sockfd;
char* message;
struct sockaddr_in servaddr;
int n;
char buf[64];
//echo_client "xxxx" ——所以判断是否为2
if (argc != 2) {
fputs("Usage: ./echo_client message \n",stderr);
exit(1);
}
message = argv[1];
printf("message: %s\n",message);
sockfd = socket(AF_INET,SOCK_STREAM,0);
memset(&servaddr,'\0',sizeof(struct sockaddr_in));
servaddr.sin_family = AF_INET;
//inet_pton(AF_INET,SERVER_IP,&servaddr.sin_addr);
inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr);
servaddr.sin_port = htons(SERVER_PORT); //转换为网络字节序
connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
write(sockfd,message,strlen(message));
n = read(sockfd, buf, sizeof(buf)-1);
if (n > 0) {
buf[n] = '\n';
printf("receive: %s\n",buf);
} else {
perror("error!");
}
printf("finished!\n");
close(sockfd);
return 0;
}
测试