目录
1.头文件
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
2.服务端代码
2.1 创建子线程函数
void *thread(void *p)
{
pthread_t tid1,tid2;
int connFd=*((int *)p);
char buf[100];
pthread_create(&tid1,NULL,threadsend,p);
pthread_create(&tid2,NULL,threadrecv,p);
return NULL;
}
2.2 接收信息函数
void *threadrecv(void *p)
{
char buf[100];
int connFd=*((int *)p);
while(1)
{
int ret;
memset(buf,0,sizeof(buf));
ret=recv(connFd,buf,sizeof(buf),0);
if(ret<0)
{
perror("recv error");
return NULL;
}
else if(ret==0)
{
exit(0);
}
printf("from client: %s\n",buf);
}
}
2.3 发送信息函数
void *threadsend(void *p)
{
int connFd=*((int *)p);
char buf[100];
while(1)
{
gets(buf);
send(connFd,buf,sizeof(buf),0);
printf("server send ok\n");
}
return NULL;
}
2.4 主函数
int main()
{
//监听套接字文件描述符
int listenFd = -1;
//连接套接字的文件描述符
int connFd = -1;
//服务器的地址结构
struct sockaddr_in servAddr = {0};
//客户端的地址结构
struct sockaddr_in cliAddr = {0};
socklen_t len = sizeof(cliAddr);
int ret;
//创建套接字
listenFd = socket(PF_INET, SOCK_STREAM, 0);
if(listenFd < 0)
{
perror("socket error!\n");
return -1;
}
printf("socket ok!\n");
//绑定ip地址和端口号
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(listenFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("bind error!");
close(listenFd);
return -1;
}
printf("bind ok!\n");
//创建监听队列(使得主动的套接字变成可以被连接的被动套接字)
ret = listen(listenFd, 1);
if(ret < 0)
{
perror("listen error");
close(listenFd);
return -1;
}
printf("listening....\n");
//等待并建立连接
connFd = accept(listenFd, (struct sockaddr *)&cliAddr, &len);
if(connFd < 0)
{
perror("accept error!");
close(listenFd);
return -1;
}
printf("IP:%s,PORT:%d accept ok!\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
while(1)
{
pthread_t tid;
pthread_create(&tid,NULL,thread,&connFd);
}
//关闭套接字
close(listenFd);
close(connFd);
return 0;
}
3.客户端代码
3.1 接收信息函数
void *threadrecv(void *p)
{
char buf[100];
int connFd=*((int *)p);
while(1)
{
int ret;
ret=recv(connFd,buf,sizeof(buf),0);
if(ret<0)
{
perror("recv error");
return NULL;
}
printf("from server: %s\n",buf);
}
}
3.2 发送信息函数
void *threadsend(void *p)
{
int connFd=*((int *)p);
char buf[100];
while(1)
{
gets(buf);
if(strcmp(buf,"quit")==0)
{
exit(0);
}
send(connFd,buf,sizeof(buf),0);
printf("client send ok\n");
}
return NULL;
}
3.3 主函数
int main()
{
int sockFd = -1;
//服务器的地址结构
struct sockaddr_in servAddr = {0};
int ret;
//创建套接字
sockFd = socket(PF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
perror("socket error!\n");
return -1;
}
printf("socket ok!\n");
//按照服务器的ip地址和端口号连接服务器
servAddr.sin_family = PF_INET;
servAddr.sin_port = htons(10086);
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = connect(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
if(ret < 0)
{
perror("connect error!");
close(sockFd);
return -1;
}
pthread_t tid1,tid2;
printf("connect ok!\n");
while(1)
{
pthread_create(&tid1,NULL,threadsend,&sockFd);
pthread_create(&tid2,NULL,threadrecv,&sockFd);
}
//关闭套接字
close(sockFd);
return 0;
}
4. 运行结果