项目:
制作一个简易的聊天室,实现实时非单机聊天
知识点:
总体框架:
socket() 创造套接字函数:
然后设置 bind() ,调整 IP 参数:
然后设置 listen() :
然后设置 accept() :
收发数据 recv(), send()/sendto(), read(), write() :
最后关闭 close() :
因为本身 socket
是一种文件描述符,所以最后要关闭打开的文件
服务端:
1.创建sd
//创建sd
sd = socket(AF_INET,SOCK_STREAM,0);
if(sd == -1)
{
perror("create sd failed");
return -1;
}
2.配置ip,端口属性
//设置ip,端口
server_ip.sin_family = AF_INET;
server_ip.sin_port = htons(5678);
server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
memset(server_ip.sin_zero,0,8);
3.绑定ip和客户端
//绑定ip和客户端
error = bind(sd,(struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
if(error == -1)
{
perror("create bind failed");
close(sd);
return -1;
}
4.设置最大链接数,这个宏定义MAX_LISLEN=2,因为我这里只连接2个客户端,可以设置多个
//设置最大链接数
error = listen(sd, MAX_LISLEN);
if(error == -1)
{
perror("create listem failed");
close(sd);
return -1;
}
5.等待客户端连接
ad[i] = accept(sd,(struct sockaddr *)(&remote_ip),&remote_len);
if(ad[i] == -1)
{
perror("create ad failed");
close(sd);
return -1;
}
6.创造新线程,不断读取客户端发送的数据,别写入另外一个客户端
void * pthread_fun(void * arg)
{
while(1)
{
memset(buf,0,100);
read(ad[(int )arg],buf,100);
write(ad[((int )arg + 1) % 2],buf,100);
}
return (void *) 0;
}
客户端 :
1.创建sd
//创建sd
sd = socket(AF_INET,SOCK_STREAM,0);
if(sd == -1)
{
perror("create sd failed");
return -1;
}
2.配置ip,端口属性
//设置ip,端口
server_ip.sin_family = AF_INET;
server_ip.sin_port = htons(5678);
server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
memset(server_ip.sin_zero,0,8);
3.连接服务端
//链接服务端
error = connect(sd, (struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
if(error == -1)
{
perror("create connect failed");
close(sd);
return -1;
}
4.创建两个新线程,不断写数据个服务端,不断从服务端读数据
void * pthread_fun_write(void * arg)
{
while(1)
{
memset(buf_write,0,100);
scanf("%s",buf_write);
write(sd,buf_write,100);
}
}
void * pthread_fun_read(void * arg)
{
while(1)
{
memset(buf_read,0,100);
read(sd,buf_read,100);
printf("client2:%s\n",buf_read);
}
}
附录
服务端代码
#include
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#define MAX_LISLEN 2
char buf_write[100];
char buf[100];
int ad[2];
struct sockaddr_in server_ip, remote_ip;
void * pthread_fun(void * arg)
{
while(1)
{
memset(buf,0,100);
read(ad[(int )arg],buf,100);
write(ad[((int )arg + 1) % 2],buf,100);
}
return (void *) 0;
}
int main()
{
pthread_t tid[2];
int server_len , remote_len;
int error, sd ;
int i = 0;
//创建sd
sd = socket(AF_INET, SOCK_STREAM ,0);
if(sd == -1)
{
perror("create sd failed");
return -1;
//close(sd);
}
//设置ip,端口
server_ip.sin_family = AF_INET;
server_ip.sin_port = htons(5678);
server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
memset(server_ip.sin_zero,0,8);
//绑定ip和客户端
error = bind(sd,(struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
if(error == -1)
{
perror("create bind failed");
close(sd);
return -1;
}
//设置最大链接数
error = listen(sd, MAX_LISLEN);
if(error == -1)
{
perror("create listem failed");
close(sd);
return -1;
}
remote_len = sizeof(struct sockaddr);
while(1)
{
//等待客户端申请
ad[i] = accept(sd,(struct sockaddr *)(&remote_ip),&remote_len);
if(ad[i] == -1)
{
perror("create ad failed");
close(sd);
return -1;
}
else
{
printf("client%d 加入聊天室\n",i+1);
}
//新线程,功能:不断读数据
error = pthread_create(&tid[i],NULL,pthread_fun,(void*) i);
if(error != 0)
{
perror("create pthread_fun failed");
close(ad[i]);
close(sd);
return -1;
}
i++;
}
close(sd);
return 0;
}
客户端1代码
#include
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
int sd;
char buf_write[100];
char buf_read[100];
struct sockaddr_in server_ip, remote_ip;
void * pthread_fun_write(void * arg)
{
while(1)
{
memset(buf_write,0,100);
scanf("%s",buf_write);
write(sd,buf_write,100);
}
}
void * pthread_fun_read(void * arg)
{
while(1)
{
memset(buf_read,0,100);
read(sd,buf_read,100);
printf("client2:%s\n",buf_read);
}
}
int main()
{
int server_len,remote_len;
pthread_t tid_read,tid_write;
int error;
sd = socket(AF_INET,SOCK_STREAM,0);
if(sd == -1)
{
perror("create sd failed");
return -1;
}
//设置ip,端口
server_ip.sin_family = AF_INET;
server_ip.sin_port = htons(5678);
server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
memset(server_ip.sin_zero,0,8);
//链接服务端
error = connect(sd, (struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
if(error == -1)
{
perror("create connect failed");
close(sd);
return -1;
}
error = pthread_create(&tid_write,NULL,pthread_fun_write,NULL);
if(error != 0)
{
perror("create pthread write failed");
close(sd);
return -1;
}
error = pthread_create(&tid_read,NULL,pthread_fun_read,NULL);
if(error != 0)
{
perror("create pthread read failed");
close(sd);
return -1;
}
pthread_join(tid_write,NULL);
pthread_join(tid_read,NULL);
return 0;
}
客户端2代码
#include
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
int sd;
char buf_write[100];
char buf_read[100];
struct sockaddr_in server_ip, remote_ip;
void * pthread_fun_write(void * arg)
{
while(1)
{
memset(buf_write,0,100);
scanf("%s",buf_write);
write(sd,buf_write,100);
}
}
void * pthread_fun_read(void * arg)
{
while(1)
{
memset(buf_read,0,100);
read(sd,buf_read,100);
printf("client1:%s\n",buf_read);
}
}
int main()
{
int server_len,remote_len;
pthread_t tid_read,tid_write;
int error;
sd = socket(AF_INET,SOCK_STREAM,0);
if(sd == -1)
{
perror("create sd failed");
return -1;
}
//设置ip,端口
server_ip.sin_family = AF_INET;
server_ip.sin_port = htons(5678);
server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
memset(server_ip.sin_zero,0,8);
error = connect(sd, (struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
if(error == -1)
{
perror("create connect failed");
close(sd);
return -1;
}
error = pthread_create(&tid_write,NULL,pthread_fun_write,NULL);
if(error != 0)
{
perror("create pthread write failed");
close(sd);
return -1;
}
error = pthread_create(&tid_read,NULL,pthread_fun_read,NULL);
if(error != 0)
{
perror("create pthread read failed");
close(sd);
return -1;
}
pthread_join(tid_write,NULL);
pthread_join(tid_read,NULL);
return 0;
}
写运行服务端创建sd,再运行客户端连接服务端,再不断加入客户端,注意最大加入数
运行结果:
想得美,直接动手