服务器端(server.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#define ERROR -1 //异常退出
#define NOR_MAL 1 //正常退出
#define Max 124
const ushort port = 49999;//端口号
static int server_fd;//服务器的文件描述符
//服务器的初始化
int server_init(ushort port)
{
//建立流式套接字
server_fd = socket(AF_INET,SOCK_STREAM,0);
if(server_fd == -1){
perror("socket()");
goto ERR_STEP;
}
//服务端的地址结构(ipv4)
//htons进行大小端转化
//INADDR_ANY表示任意ip地址,系统提供的宏
struct sockaddr_in server_addr = {
.sin_family = AF_INET,
.sin_port = htons(port),
.sin_addr.s_addr = htonl(INADDR_ANY),
};
//服务端的地址长度
socklen_t len = sizeof(server_addr);
//绑定套接字,地址
if(bind(server_fd,(struct sockaddr *)&server_addr,len) < 0){
perror("bind");
goto ERR_STEP;
}
//设置监听套接字,允许最大连接的套接字
if(listen(server_fd,10) < 0){
perror("listen");
goto ERR_STEP;
}
//返回文件描述符
return server_fd;
ERR_STEP:
close(server_fd);
return ERROR;
}
int main(int argc,char *argv[])
{
//初始化
int fd = server_init(port);
//客户端的地址
struct sockaddr_in client_addr;
//客户端的地址长度
socklen_t len = sizeof(client_addr);
printf("waiting for conncet ...\n");
//设置连接套接字
int connfd = accept(fd,(struct sockaddr*)&client_addr,&len);
if(fd < 0){
perror("accept");
goto ERR_STEP;
}
//打印客户端的ip地址和端口号
printf("client ip is %s\n",inet_ntoa(client_addr.sin_addr));
printf("client port is %u\n",ntohs(client_addr.sin_port));
//循环接收数据
while(1){
//读缓冲区
char readBuf[Max] = {0};
//每次读取数据之前先清空缓冲区
memset(readBuf,0,sizeof(readBuf));
//读取数字,从连接套接字中读取,如果填写的不是connfd而是fd的话
//读取数据的时候应该从客户端中读取
//系统会报错,提示Transport endpoint is not connected
int ret = read(connfd,readBuf,sizeof(readBuf)-1);
if(ret > 0){//返回值大于0表示读取数据成功
printf("%s\n",readBuf);
}else if(ret == 0){//返回值为0的时候,表示客户端断开连接
printf("the client is disconnect\n");
goto ERR_STEP;
}else {
printf("recv failed\n");
goto ERR_STEP;
}
//当接收到的数据为quit的时候,结束退出
int err = strncmp(readBuf,"quit",4);
if(err == 0){
printf("client is quit...\n");
return NOR_MAL;
}
}
ERR_STEP:
close(fd);
return ERROR;
}
客户端实现(clinet.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#define ERROR -1
#define Max 124
//服务器的ip地址和端口号
//这里用的是回环地址,适用于同一台计算机上
//如果采用的是两台计算机,应该填充服务器的具体ip地址
const char *ip = "127.0.0.1";
const ushort port = 49999;
int main(int argc,const char *argv[])
{
//建立流式套接字
int server_fd = socket(AF_INET,SOCK_STREAM,0);
if(server_fd == -1){
perror("socket()");
goto ERR_STEP;
}
//服务器的地址结构
//inet_addr将字符串形式的ip地址转换成网络字节序的整型值
struct sockaddr_in server_addr = {
.sin_family = AF_INET,
.sin_port = htons(port),
.sin_addr.s_addr = inet_addr(ip),
};
//服务器的地址长度
socklen_t len = sizeof(server_addr);
//连接服务器
if((connect(server_fd,(struct sockaddr*)&server_addr,len))< 0){
perror("connect");
goto ERR_STEP;
}else{
printf("connect successed\n");
}
//循环发送数据
while(1){
//写缓冲区
char writeBuf[Max] = {0};
memset(writeBuf,0,sizeof(writeBuf));
scanf("%s",writeBuf);
int ret = write(server_fd,writeBuf,strlen(writeBuf));
if(ret < 0){
perror("write");
goto ERR_STEP;
}
//当输入quit的时候,客户端断开连接
int err = strncmp(writeBuf,"quit",4);
if(err == 0){
printf("disconnet...\n");
goto ERR_STEP;
}
}
ERR_STEP:
close(server_fd);
return ERROR;
}
运行:
服务器:gcc server.c -o s (-o表示生成可执行文件)
客户端:gcc client.c -o c