1.图解客户端与服务端交互流程
socket简单实践
服务端
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <fcntl.h>
#include <unistd.h>
unsigned short server_Port = 1234; // 服务器端口
const char *IP = "192.168.80.132"; // 服务器IP
/**字母转大写*/
void upper(char *buf)
{
char *pointer = buf;
while (*pointer != '\n')
{
if (*pointer >= 'a' && *pointer <= 'z')
*pointer -= 32;
pointer++;
}
return;
}
int main()
{
//创建套接字
int server_Socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_Addr;
server_Addr.sin_family = AF_INET;
server_Addr.sin_port = htons(server_Port);
int flag = inet_aton(IP, &(server_Addr.sin_addr));
if (!flag)
{
perror("IP transfer failed!\n");
}
//绑定服务器IP地址端口号
bind(server_Socket, (struct sockaddr *)&server_Addr, sizeof(server_Addr));
listen(server_Socket, 5);
while (1)
{
printf("等待用户连接!\n");
struct sockaddr_in client_Addr;
int addrlen = sizeof(client_Addr);
int conn_Socket = accept(server_Socket, (struct sockaddr *)&client_Addr, &addrlen);
if (conn_Socket == -1)
{
perror("conn failed!\n");
}
//提取客户端信息
char *client_Ip = inet_ntoa(client_Addr.sin_addr);
unsigned short client_Port = ntohs(client_Addr.sin_port);
printf("客户端: %s:%hu已连接!\n", client_Ip, client_Port);
while (1)
{
char buf[100];
memset(buf, '\0', 100);
int count = read(conn_Socket, buf, 99);
if (count == -1)
{
printf("客户端: %s:%hu连接故障!\n", client_Ip, client_Port);
}
else if (count == 0)
{
printf("客户端: %s:%hu断开连接!\n", client_Ip, client_Port);
close(conn_Socket);
break;
}
else
{
printf("客户端: %s:%hu消息:%s", client_Ip, client_Port, buf);
upper(buf);
write(conn_Socket, buf, 99);
}
}
}
return 0;
}
客户端
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <fcntl.h>
#include <unistd.h>
unsigned short server_Port = 1234; // 服务器端口
const char *IP = "192.168.80.132"; // 服务器IP
int main()
{
// 创建套接字
int client_Socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_Addr;
server_Addr.sin_family = AF_INET;
server_Addr.sin_port = htons(server_Port);
int flag = inet_aton(IP, &(server_Addr.sin_addr));
if (!flag)
{
perror("IP transfer failed!\n");
}
// 连接服务器
flag = connect(client_Socket, (struct sockaddr *)&server_Addr, sizeof(server_Addr));
if (flag == -1)
{
perror("conn failed!\n");
return 0;
}
printf("成功连接服务端!\n");
while (1)
{
// 终端输入
printf("请输入消息:");
char buf[100];
fgets(buf, 99, stdin);
// input end quit!
if (strncmp(buf, "end", 3) == 0)
{
printf("用户退出!\n");
close(client_Socket);
break;
}
write(client_Socket, buf, 99);
int count = read(client_Socket, buf, 99);
if (count == -1)
{
printf("服务器连接故障!\n");
}
else if (count == 0)
{
printf("与服务器断开连接!\n");
close(client_Socket);
break;
}
else
{
printf("服务端返回消息:%s", buf);
}
}
return 0;
}
套接字赋值
当我们对套接字进行赋值时,需要将IP地址以及端口号转换为网络字节序。port类型为 unsigned short;对于IP字符的转换有多个接口,可自行查阅。
read判定退出状态
无论当我们关闭哪一方套接字时,都会向另一方发送一个EOF(表明数据发送完毕),所以读取到的字符数为0。
总结
本节仅对socket最基本的轮子进行了使用的介绍,让入门的同学知道客户端与服务端的建立连接并进行通信的流程,下一节我们将深入了解这些轮子。
标签:SOCKET,IP,server,详解,Addr,轮子,include,buf,Socket From: https://www.cnblogs.com/loserli/p/17335080.html