服务器端代码:
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
/* 1. socket() 创建socket
2. bind() 绑定服务器地址结构
由于网络字节序采用大端法:高位存低地址
本地字节序采用小端法:高位存高地址
所以在,绑定之前,需要先进行ip的转换。
本地字节序--》网络字节序 inet_pton()
简化的方法:htonl(INADDR_ANY); 采用"隐式绑定",获取本机任意有效IP
网络字节序--》本地字节序 inet_ntop()
端口也需要进行相应的转化;
本地--》网络:htons()
网络--》本地:ntohs()
3. listen() 设置监听上限
4. accept() 阻塞监听客户端连接
5. read(fd) 读socket获取客户端数据
6. 小--大写 toupper() 大写--小写 tolower()
7. write(fd)
8. close();
*/
#define SER_PORT 6780
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main (int argc,char *argv[])
{
int lfd = 0,cfd = 0;
int ret,i,num;
/* 定义服务器地址结构 和 客户端地址结构*/
struct sockaddr_in ser_addr,cli_addr;
/* 客户端地址结构大小*/
socklen_t cli_addr_len;
char cli_ip[1024],buf[1024];
/*地址结构 ip+端口号*/
ser_addr.sin_family = AF_INET; /* IPv4*/
ser_addr.sin_port = htons(SER_PORT); /* 转为网络字节序的 端口号*/
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 获取本机任意有效IP*/
lfd = socket(AF_INET,SOCK_STREAM,0);
if(lfd == -1){
sys_err("socket fail \n");}
num = bind(lfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));
if(num == -1) { sys_err("bind fail \n");}
num = listen(lfd,128);
if(num == -1) {sys_err("listen fail \n");}
cli_addr_len = sizeof(cli_addr);
/*accept的第二个参数是传出参数,传出和该服务器连接的客户端*/
cfd = accept(lfd,(struct sockaddr *)&cli_addr,&cli_addr_len);
if(cfd == -1){ sys_err("accept fail \n");}
/*根据accept传出参数,获取客户端 ip 和 port*/
printf("client ip=%s,端口号=%d \n",inet_ntop(AF_INET,&ser_addr.sin_addr.s_addr,cli_ip,sizeof(cli_ip)),
ntohs(cli_addr.sin_port));
while(1){
ret = read(cfd,buf,sizeof(buf));
/*重定向,将读到的显示在屏幕上*/
write(STDOUT_FILENO,buf,ret);
/*小写转大写*/
for(i=0;i<ret;i++) buf[i]=toupper(buf[i]);
/*tolower()函数可以实现大写转小写*/
write(cfd,buf,ret);
}
close(lfd);
close(cfd);
return 0;
}
客户端代码:
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
/*
1. socket() 创建socket
2. connect(); 与服务器建立连接
3. write() 写数据到 socket
4. read() 读转换后的数据。
5. 显示读取结果
6. close()
*/
#define SER_PORT 6780
void sys_err (const char *str)
{
perror(str);
exit(1);
}
int main(int argc,char *argv[])
{
int cfd;
int ret,count=5;
struct sockaddr_in ser_addr;
char buf[1024];
/*SOCK_STREAM:TCP
SOCK_DGRAM :UDP*/
cfd = socket(AF_INET,SOCK_STREAM,0);
if(cfd == -1) sys_err("socket fail \n");
/*设置地址结构。注意:这里使用的是服务器地址结构。因为要和服务器建立连接*/
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
/*注意:这个地方不能像服务器一样,使用ONADDR_ANY;而是要指定Ip*/
inet_pton(AF_INET,"127.0.0.1",&ser_addr.sin_addr);
/*与服务器建立连接*/
ret = connect(cfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));
if(ret != 0) sys_err("connect fail \n");
while(--count)
{
write(cfd,"hello\n",6);
ret = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,ret);
sleep(1);
}
close(cfd);
return 0;
}