例子:大写转小写。
注意:代码都是运行在Linux内核中。
服务器端:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <ctype.h>
int main()
{
// 1、创建套接字
int lfd = socket(AF_INET, SOCK_STREAM, 0);
// 2、绑定IP和端口号
struct sockaddr_in server_addr; // 创建结构体
server_addr.sin_family = AF_INET; // 指定IPv4
server_addr.sin_port = htons(8888); // 将端口号转换为网络字节序
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 将本地任意IP转为网络字节序
bind(lfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); // 绑定,注意强转
// 3、监听
listen(lfd,128); // 上限128
// 4、阻塞等待客户端链接(获得一个新的指向客户端文件描述符)
struct sockaddr_in client_addr; // 传入参数:要先定义,然后传入
socklen_t client_addr_len = sizeof(client_addr); // 传入传出参数:要先定义赋值,然后传入
int cfd = accept(lfd, (struct sockaddr*)&client_addr, &client_addr_len); // 指向客户端
// 输出客户端信息
char ip[256] = {0}; // 用于存储IP字符串
printf("client IP: %s 端口号: %d\n",
inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ip, sizeof(ip)),
ntohs(client_addr.sin_port) ); // 2个函数的返回值分别是IP和端口号
// 以下为通信
char buf[256];
while(1) // 实现循环操作
{
// 读取客户端传来的内容
int n = read(cfd, buf, sizeof(buf)); // 返回值是读到的字节数(字母个数)
// 转换字母
for(int i = 0; i < n; i++)
buf[i] = toupper( buf[i] );
// 写回给客户端
write(cfd, buf, n);
}
//关闭
close(lfd);
close(cfd);
return 0;
}
客户端:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
int main()
{
// 创建客户端socket
int cfd = socket(AF_INET, SOCK_STREAM, 0);
// 客户端应该绑定bind自己的IP和端口,但也可以不绑定,系统会帮助做“隐式绑定”
// 注意:服务器可以做隐式绑定吗?
// 答: 不可以,因为隐式绑定,服务器的IP和端口不固定,客户端不知道该连接哪
// 链接服务器
struct sockaddr_in server_addr; // 因为要链接服务器,存储的服务器的IP地址和端口号
// 指定服务器的地址信息
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr.s_addr); // 转 网络字节序
socklen_t addrlen = sizeof(server_addr); // 指定服务器的地址长度
connect(cfd, (struct sockaddr*)&server_addr, addrlen); // 链接服务器
char buf[256];
while(1)
{
// 向服务器传数据
fgets(buf, sizeof(buf), stdin); // 从键盘输入,存入buf
// 注意:fgets 特性,一直接收键盘输入,以回车作为结尾,然后自动给加\0
// 举例 hello 经过fgets 存入buf的是 “hello\n\o”
write(cfd, buf, strlen(buf)); // 因此,此处用strlen,而不是sizeof
// 服务器处理后,客户端读取数据
int n = read(cfd, buf, sizeof(buf));
// 写入屏幕
write(STDOUT_FILENO, buf, n);
}
close(cfd);
return 0;
}