只需修改IP即可使用
服务器
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#define SERV_PORT 5001 //5000~65535
void cli_data_handle(void *arg);
void cli_data_handles(void *arg);
int main()
{
int fd=-1;
struct sockaddr_in sin;
/*1 create socket fd*/
if(( fd=socket(AF_INET,SOCK_STREAM,0))<0){
perror ("socket");
exit(-1);
}
int b_reuse=1;
setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&b_reuse,sizeof(int));
//give value of sin
bzero(&sin,sizeof(sin)); //clear 0
sin.sin_family=AF_INET; //struct get value
sin.sin_port = htons(SERV_PORT);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
/*2 bind ip and ip*/
bind(fd,(struct sockaddr *)&sin,sizeof(sin));
/*3 listen */
if(listen(fd,5)<0)
{
perror("listen");
exit(-1);
}
/*4 wait */
pthread_t tid,sid;
int newfd=-1;
struct sockaddr_in cin;
socklen_t addrlen=sizeof(cin);
while(1)
{
char buff[BUFSIZ];
if((newfd=accept(fd,(struct sockaddr *)&cin,&addrlen))<0)
{
perror("accpet");
exit(-1);
}
char ipv4_addr[16];
inet_ntop(AF_INET,(void *)&cin.sin_addr,ipv4_addr,sizeof(cin));
printf("client(%s,%d) is connect\n",ipv4_addr,htons(cin.sin_port));
pthread_create(&tid,NULL,(void *)cli_data_handle,(void *)&newfd);
pthread_create(&sid,NULL,(void *)cli_data_handles,(void *)&newfd);
scanf("%s",buff);
write(newfd,buff,BUFSIZ-1);
}
close(fd);
return 0;
}
void cli_data_handle(void *arg)
{
int newfd = *(int *)arg;
printf ("handler thread: newfd =%d\n",newfd) ;
//..和newfd进行数据读写
int ret = -1;
char buf [BUFSIZ] ;
while (1)
{
bzero (buf, BUFSIZ) ;
do {
ret = read (newfd, buf, BUFSIZ-1) ;
}while(ret < 0 && EINTR == errno) ;
if(ret<0){
perror ("read") ;
exit(1) ;
}
if(!ret) { //对方 已经关闭
break;
}
printf("C:---> %s", buf);
if(strncasecmp(buf,"quit",4)==0)
{
printf("Client() is exiting! \n");
break;
}
}
close (newfd);
}
void cli_data_handles(void *arg)
{
int newfd = *(int *)arg;
char buff [BUFSIZ] ;
while (1)
{
bzero(buff, BUFSIZ);
read(0,buff,BUFSIZ-1);
write(newfd,buff,BUFSIZ-1);
}
close (newfd);
}
客户端
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#define SERV_PORT 5001 //5000~65535
#define SERV_IP_ADDR "192.168.1.230" //local ip
int main()
{
int fd=-1;//定义fd备用
struct sockaddr_in sin;//定义填充结构体备用,强转为sockaddr使用
/*1 create socket fd*/
if((fd=socket(AF_INET,SOCK_STREAM,0))<0){//申请文件描述符
perror ("socket");
exit(-1);
}
/*2.connect with sever net*/
bzero(&sin,sizeof(sin));//清零结构体 并给结构体变量赋值
sin.sin_family=AF_INET;
sin.sin_port = htons(SERV_PORT);
sin.sin_addr.s_addr=inet_addr(SERV_IP_ADDR);
connect(fd,(struct sockaddr *)&sin,sizeof(sin));//在套接字上启动连接
/*3 .read write*/
fd_set rset;//定义一个rset集合用来存放文件描述符
int maxfd = -1;//定义最大容量
int ret=-1;
struct timeval tout;//定义超时结构体
char buf[BUFSIZ];
while(1) {
FD_ZERO(&rset);//清0
FD_SET(0,&rset);//将标准输入0的文件描述符存入
FD_SET(fd,&rset);//将网络套接字socket的文件描述符fd存入
maxfd=fd;//将此时的fd记为最大文件描述符
tout.tv_sec=5;//超时结构体秒赋值
tout.tv_usec=0;//超时结构体毫秒赋值
select(maxfd+1,&rset,NULL,NULL,&tout);// 当调用select()时,由内核根据IO状态修改fd_set的内容,
//由此来通知执 行了select()的进程哪一Socket或文件可读或可写。主要用于Socket通信当中!
if(FD_ISSET(0,&rset)) { //标准键盘.上有输入
//读取键盘输入,发送到网络套接字fd
bzero(buf,BUFSIZ);
do {
ret=read(0,buf,BUFSIZ-1);//读取
} while(ret<0&&EINTR == errno);
if(ret < 0) {
perror("read"); //读取失败 继续
continue;
}
if (!ret)
continue; //读取为空
if (write(fd,buf,strlen(buf)) <0) {// 将在标准输入读取到的内容 发送(写入)给网络套接字
perror("write() to socket");
continue;
}
if (!strncasecmp (buf,"quit",4)) { //用户输入了 quit字符
printf("Client is exiting!\n");
break; //接受到quit 退出
}
}
if(FD_ISSET(fd,&rset)){//服务 器给发送过来了数据
//读取套接字数据,处理
bzero(buf,BUFSIZ);
do{
ret = read(fd,buf,BUFSIZ-1);//读取网络套接字发送过来的内容
}while(ret < 0 && EINTR == errno);
if(ret < 0){
perror("read from socket");
continue;
}
if(!ret) break; /*服务器关闭*/
//There is a BUG, FIXME! !
printf("S:--->%s\n",buf); //将接受的网络套接字的内容由标准输出 输出
if (!strncasecmp (buf,"quit",4)) { //用户输入了 quit字符
printf("Sender Client is exiting!\n");
break;
}
}
}
/*4 close fd*/
close(fd); //关闭网络套接字
return 0;
}