@TOCSocket 是网络编程得接口 所以网络编程又叫Socket 编程
https 是80得默认端口 ssh默认端22
域名解析系统DNS
任何域名都可以解析到ip地址
tcp /ip网络就是 物理链路
网络通信与Socket
tcp/ip协议四层:
应用层
传输层
网络层
数据链路层
服务端
#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;//服务端的标签
//1.美女创建信箱
sock = socket(AF_INET, SOCK_STREAM, 0);//创建信箱
//2.清空标签,写上地址和端口号
bzero(&server_addr, sizeof(server_addr));//标签清空
server_addr.sin_family = AF_INET;//选择协议族IPV4//协议写到标签选择协议族IPv4
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//监听本地所有IP地址//标签绑定本地所有得ip地址用htonl函数
server_addr.sin_port = htons(SERVER_PORT);//绑定端口号
//实现标签贴到收信得信箱上
bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
//把信箱挂置到传达室,这样,就可以接收信件了
listen(sock, 128);//同一时刻来得信件接收 128封将信箱挂到传达室
//万事俱备,只等来信
printf("等待客户端的连接\n");
int done = 1;
while (done) {
struct sockaddr_in client;//客户端得标签
int client_sock, len, i;//客户端的sock 发来信息的长度
char client_ip[64];//保存客户端的IP地址
char buf[256];//保存客户端发来的信息
socklen_t client_addr_len;//sock的长度
client_addr_len = sizeof(client);//获取长度
client_sock = accept(sock, (struct sockaddr*)&client, &client_addr_len);//接收信箱 返回跟客户端通信得sock
//打印客服端IP地址和端口号
printf("client ip: %s\t port : %d\n",
inet_ntop(AF_INET, &client.sin_addr.s_addr, client_ip, sizeof(client_ip)),
ntohs(client.sin_port));//获得客户端得ip和端口号
/*读取客户端发送的数据*/
len = read(client_sock, buf, sizeof(buf) - 1);//读取客户端发来的消息
buf[len] = '\0';
printf("receive[%d]: %s\n", len, buf);
//转换成大写
for (i = 0; i < len; i++) {
/*if(buf[i]>='a' && buf[i]<='z'){
buf[i] = buf[i] - 32;
}*/
buf[i] = toupper(buf[i]);
}
len = write(client_sock, buf, len);//写入消息
printf("finished. len: %d\n", len);
close(client_sock);//关闭客户端的sock
}
close(sock);//关闭服务端的sock
return 0;
}
客户端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>//系统调用
#include<sys/socket.h>//网络编程socket
#include<netinet/in.h>//网络地址
#define SERVER_PORT 666
int main(int argc, char* argv[])
{
int sockfd;//客户端邮箱
char* message;//用户要发送的数据
struct sockaddr_in servaddr;//信封
int n;//接收服务端信息的长度
char buf[64];//接收服务端信息的内容
if (argc != 2)//如果用户没有要发送的数据
{
fputs("Usage: ./client message\n", stderr);//启动程序的格式不正常 并输出到标准出错
exit(1);//异常出错
}
message = argv[1];//保存用户发送的数据
printf("message:%s\n", message);
/*int socket(int domain, int type, int protocol);
其中 “int domain”参数表示套接字要使用的协议簇,协议簇的在“linux/socket.h”里有详细定义,常用的协议簇:
AF_UNIX(本机通信)
AF_INET(TCP/IP – IPv4)
AF_INET6(TCP/IP – IPv6)
其中 “type”参数指的是套接字类型,常用的类型有:
SOCK_STREAM(TCP流)
SOCK_DGRAM(UDP数据报)
SOCK_RAW(原始套接字)
最后一个 “protocol”一般设置为“0”,也就是当确定套接字使用的协议簇和类型时,这个参数的值就为0,但是有时候创建原始套接字时,并不知道要使用的协议簇和类型,也就是domain参数未知情况下,这时protocol这个参数就起作用了,它可以确定协议的种类。
socket是一个函数,那么它也有返回值,当套接字创建成功时,返回套接字,失败返回“-1”,错误代码则写入“errno”中。
*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);//创建信箱//使用tcp
memset(&servaddr, '\0', sizeof(servaddr));//将信封标签清空
servaddr.sin_family = AF_INET;//选择协议族IPV4//协议写到标签选择协议族IPv4
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);//将字符串的ip地址转换为网洛识别的ip地址127.0.0.1是本机与本机通信的高效接口
servaddr.sin_port = htons(SERVER_PORT);//绑定端口号htons将端口转换为字节序
connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));//用信封的信息链接服务端的邮箱
write(sockfd, message, strlen(message));//通过邮箱写入数据
n= read(sockfd, buf, sizeof(buf) - 1);//读取客户端发来的消息返回消息的长度
if (n > 0)//如果服务端有数据来了
{
buf[n] = '\0';
printf("receive[%d]: %s\n", n, buf);
}
else//出现问题了
{
perror("error!!!");
}
printf("finished.\n");
close(sockfd);//关闭套接字
return 0;
}