基本的局域网聊天
局域网聊天TCP服务端:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineQUEUE 20int conn;void thread_task() {
}int main() {
//printf("%d\n",AF_INET);
//printf("%d\n",SOCK_STREAM);intss = socket(AF_INET, SOCK_STREAM,0);
//printf("%d\n",ss);struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
//printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(ss, (structsockaddr* ) &server_sockaddr,sizeof(server_sockaddr))==-1) {
perror("bind");
exit(1);
}
if(listen(ss, QUEUE) == -1) {
perror("listen");
exit(1);
}
struct sockaddr_in client_addr;
socklen_t length =sizeof(client_addr);
///成功返回非负描述字,出错返回-1conn = accept(ss, (structsockaddr*)&client_addr, &length);
if( conn <0 ) {
perror("connect");
exit(1);
}
charbuffer[1024];
//创建另外一个线程
//std::thread t(thread_task);
//t.join();
//char buf[1024];
//主线程while(1) {
// memset(buf, 0 ,sizeof(buf));
// if(fgets(buf, sizeof(buf),stdin) != NULL) {
// send(conn, buf, sizeof(buf), 0);
// } memset(buffer, 0,sizeof(buffer));
intlen = recv(conn, buffer,sizeof(buffer),0);
if(strcmp(buffer,"exit\n") ==0)break;
printf("%s", buffer);
//必须要有返回数据, 这样才算一个完整的请求send(conn, buffer, len ,0);
}
close(conn);
close(ss);
return0;
}
局域网聊天TCP客户端:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #defineMYPORT 7000#defineBUFFER_SIZE 1024int main()
{
///定义sockfdintsock_cli = socket(AF_INET,SOCK_STREAM,0);
///定义sockaddr_instruct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)
{
perror("connect");
exit(1);
}
char sendbuf[BUFFER_SIZE];
char recvbuf[BUFFER_SIZE];
while(fgets(sendbuf,sizeof(sendbuf), stdin) != NULL)
{
send(sock_cli, sendbuf, strlen(sendbuf),0);///发送if(strcmp(sendbuf,"exit\n")==0)
break;
recv(sock_cli, recvbuf, sizeof(recvbuf),0);///接收 fputs(recvbuf, stdout);
memset(sendbuf, 0,sizeof(sendbuf));
memset(recvbuf, 0,sizeof(recvbuf));
}
close(sock_cli);
return0;
}
回到顶部
客户端服务端双向异步聊天源码
以上的局域网聊天应用有一个很重要的缺点, 服务器只能显示客户端发送的消息, 却无法给客户端发送消息, 这个很尴尬;
通过使用C中的select()函数, 实现一个异步聊天工具:
异步聊天服务端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineQUEUE 20int main() {
fd_set rfds;
struct timeval tv;
int retval, maxfd;
intss = socket(AF_INET, SOCK_STREAM,0);
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
//printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(ss, (structsockaddr* ) &server_sockaddr,sizeof(server_sockaddr))==-1) {
perror("bind");
exit(1);
}
if(listen(ss, QUEUE) == -1) {
perror("listen");
exit(1);
}
struct sockaddr_in client_addr;
socklen_t length =sizeof(client_addr);
///成功返回非负描述字,出错返回-1intconn = accept(ss, (structsockaddr*)&client_addr, &length);
if( conn <0 ) {
perror("connect");
exit(1);
}
while(1) {
/*把可读文件描述符的集合清空*/ FD_ZERO(&rfds);
/*把标准输入的文件描述符加入到集合中*/ FD_SET(0, &rfds);
maxfd =0;
/*把当前连接的文件描述符加入到集合中*/ FD_SET(conn, &rfds);
/*找出文件描述符集合中最大的文件描述符*/if(maxfd < conn)
maxfd = conn;
/*设置超时时间*/ tv.tv_sec =5;
tv.tv_usec =0;
/*等待聊天*/ retval =select(maxfd+1, &rfds, NULL, NULL, &tv);
if(retval == -1){
printf("select出错,客户端程序退出\n");
break;
}elseif(retval ==0){
printf("服务端没有任何输入信息,并且客户端也没有信息到来,waiting...\n");
continue;
}else{
/*客户端发来了消息*/if(FD_ISSET(conn,&rfds)){
charbuffer[1024];
memset(buffer, 0,sizeof(buffer));
intlen = recv(conn, buffer,sizeof(buffer),0);
if(strcmp(buffer,"exit\n") ==0)break;
printf("%s", buffer);
//send(conn, buffer, len , 0);把数据回发给客户端 }
/*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){
charbuf[1024];
fgets(buf, sizeof(buf), stdin);
//printf("you are send %s", buf);send(conn, buf,sizeof(buf),0);
}
}
}
close(conn);
close(ss);
return0;
}
异步聊天客户端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #defineMYPORT 7000#defineBUFFER_SIZE 1024int main()
{
int sock_cli;
fd_set rfds;
struct timeval tv;
int retval, maxfd;
///定义sockfdsock_cli = socket(AF_INET,SOCK_STREAM,0);
///定义sockaddr_instruct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)
{
perror("connect");
exit(1);
}
while(1){
/*把可读文件描述符的集合清空*/ FD_ZERO(&rfds);
/*把标准输入的文件描述符加入到集合中*/ FD_SET(0, &rfds);
maxfd =0;
/*把当前连接的文件描述符加入到集合中*/ FD_SET(sock_cli, &rfds);
/*找出文件描述符集合中最大的文件描述符*/if(maxfd < sock_cli)
maxfd = sock_cli;
/*设置超时时间*/ tv.tv_sec =5;
tv.tv_usec =0;
/*等待聊天*/ retval =select(maxfd+1, &rfds, NULL, NULL, &tv);
if(retval == -1){
printf("select出错,客户端程序退出\n");
break;
}elseif(retval ==0){
printf("客户端没有任何输入信息,并且服务器也没有信息到来,waiting...\n");
continue;
}else{
/*服务器发来了消息*/if(FD_ISSET(sock_cli,&rfds)){
char recvbuf[BUFFER_SIZE];
int len;
len = recv(sock_cli, recvbuf,sizeof(recvbuf),0);
printf("%s", recvbuf);
memset(recvbuf, 0,sizeof(recvbuf));
}
/*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){
char sendbuf[BUFFER_SIZE];
fgets(sendbuf, sizeof(sendbuf), stdin);
send(sock_cli, sendbuf, strlen(sendbuf),0);//发送memset(sendbuf,0,sizeof(sendbuf));
}
}
}
close(sock_cli);
return0;
}
回到顶部
局域网内服务端和有限个客户端聊天源码
以上的局域网聊天只能支持一个用户, 我们还要改改, 必须是支持多用户的聊天室:
局域网TCP多人聊天服务端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineQUEUE 20int ss;struct sockaddr_in client_addr;
socklen_t length =sizeof(client_addr);intconns[2] = {};intz =0;void thread_fn() {
//成功返回非负描述字,出错返回-1intconn = accept(ss, (structsockaddr*)&client_addr, &length);
if( conn <0 ) {
perror("connect");
exit(1);
}
//把连接保存到临时数组中;conns[z] = conn;
z++;
fd_set rfds;
struct timeval tv;
int retval, maxfd;
while(1) {
/*把可读文件描述符的集合清空*/ FD_ZERO(&rfds);
/*把标准输入的文件描述符加入到集合中*/ FD_SET(0, &rfds);
maxfd =0;
/*把当前连接的文件描述符加入到集合中*/ FD_SET(conn, &rfds);
/*找出文件描述符集合中最大的文件描述符*/if(maxfd < conn)
maxfd = conn;
/*设置超时时间*/ tv.tv_sec =5;
tv.tv_usec =0;
/*等待聊天*/ retval =select(maxfd+1, &rfds, NULL, NULL, &tv);
if(retval == -1){
printf("select出错,客户端程序退出\n");
break;
}elseif(retval ==0){
printf("服务端没有任何输入信息,并且客户端也没有信息到来,waiting...\n");
continue;
}else{
/*客户端发来了消息*/if(FD_ISSET(conn,&rfds)){
charbuffer[1024];
memset(buffer, 0,sizeof(buffer));
intlen = recv(conn, buffer,sizeof(buffer),0);
if(strcmp(buffer,"exit\n") ==0)break;
printf("%s", buffer);
//send(conn, buffer, len , 0);把数据回发给客户端 }
/*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){
charbuf[1024];
fgets(buf, sizeof(buf), stdin);
//printf("you are send %s", buf);for(inti=0; i
send(conns[i], buf, sizeof(buf),0);
}
}
}
}
close(conn);
}voidthread_select(int conn) {
}int main() {
ss = socket(AF_INET, SOCK_STREAM,0);
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
//printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(ss, (structsockaddr* ) &server_sockaddr,sizeof(server_sockaddr))==-1) {
perror("bind");
exit(1);
}
if(listen(ss, QUEUE) == -1) {
perror("listen");
exit(1);
}
std::thread t(thread_fn);
std::thread t1(thread_fn);
t.join();
t1.join();
close(ss);
return0;
}
局域网TCP多人聊天客户端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #defineMYPORT 7000#defineBUFFER_SIZE 1024int main()
{
int sock_cli;
fd_set rfds;
struct timeval tv;
int retval, maxfd;
///定义sockfdsock_cli = socket(AF_INET,SOCK_STREAM,0);
///定义sockaddr_instruct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)
{
perror("connect");
exit(1);
}
while(1){
/*把可读文件描述符的集合清空*/ FD_ZERO(&rfds);
/*把标准输入的文件描述符加入到集合中*/ FD_SET(0, &rfds);
maxfd =0;
/*把当前连接的文件描述符加入到集合中*/ FD_SET(sock_cli, &rfds);
/*找出文件描述符集合中最大的文件描述符*/if(maxfd < sock_cli)
maxfd = sock_cli;
/*设置超时时间*/ tv.tv_sec =5;
tv.tv_usec =0;
/*等待聊天*/ retval =select(maxfd+1, &rfds, NULL, NULL, &tv);
if(retval == -1){
printf("select出错,客户端程序退出\n");
break;
}elseif(retval ==0){
printf("客户端没有任何输入信息,并且服务器也没有信息到来,waiting...\n");
continue;
}else{
/*服务器发来了消息*/if(FD_ISSET(sock_cli,&rfds)){
char recvbuf[BUFFER_SIZE];
int len;
len = recv(sock_cli, recvbuf,sizeof(recvbuf),0);
printf("%s", recvbuf);
memset(recvbuf, 0,sizeof(recvbuf));
}
/*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){
char sendbuf[BUFFER_SIZE];
fgets(sendbuf, sizeof(sendbuf), stdin);
send(sock_cli, sendbuf, strlen(sendbuf),0);//发送memset(sendbuf,0,sizeof(sendbuf));
}
}
}
close(sock_cli);
return0;
}
回到顶部
完美异步聊天服务端和客户端源码
以上的多客户聊天不是很好, 因为只允许两个客户端连接, 体验非常差, 如果支持无限个客户端聊天的话那该多好啊, 哈哈, 这个也是可以的, 我们只要使用c++的list即可, 它是可以自增的数组(其实算是链表), 引用 头文件即可:
无限个客户聊天的 服务端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineIP "127.0.0.1"int s;struct sockaddr_in servaddr;
socklen_t len;
std::list li;void getConn() {
while(1){
intconn = accept(s, (structsockaddr*)&servaddr, &len);
li.push_back(conn);
printf("%d\n", conn);
}
}void getData() {
struct timeval tv;
tv.tv_sec =2;
tv.tv_usec =0;
while(1) {
std::list::iterator it;
for(it=li.begin(); it!=li.end(); ++it){
fd_set rfds;
FD_ZERO(&rfds);
intmaxfd =0;
intretval =0;
FD_SET(*it, &rfds);
if(maxfd < *it){
maxfd = *it;
}
retval =select(maxfd+1, &rfds, NULL, NULL, &tv);
if(retval == -1){
printf("select error\n");
}elseif(retval ==0) {
//printf("not message\n");}else{
charbuf[1024];
memset(buf, 0,sizeof(buf));
intlen = recv(*it, buf,sizeof(buf),0);
printf("%s", buf);
}
}
sleep(1);
}
}void sendMess() {
while(1) {
charbuf[1024];
fgets(buf, sizeof(buf), stdin);
//printf("you are send %s", buf);std::list::iterator it;
for(it=li.begin(); it!=li.end(); ++it){
send(*it, buf,sizeof(buf),0);
}
}
}int main() {
//new sockets = socket(AF_INET, SOCK_STREAM,0);
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = inet_addr(IP);
if(bind(s, (structsockaddr* ) &servaddr,sizeof(servaddr))==-1) {
perror("bind");
exit(1);
}
if(listen(s,20) == -1) {
perror("listen");
exit(1);
}
len =sizeof(servaddr);
//thread : while ==>> accpet std::thread t(getConn);
t.detach();
//printf("done\n");
//thread : input ==>> send std::thread t1(sendMess);
t1.detach();
//thread : recv ==>> show std::thread t2(getData);
t2.detach();
while(1){
}
return0;
}
无限个客户端连接的客户端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #defineMYPORT 7000#defineBUFFER_SIZE 1024int main()
{
int sock_cli;
fd_set rfds;
struct timeval tv;
int retval, maxfd;
///定义sockfdsock_cli = socket(AF_INET,SOCK_STREAM,0);
///定义sockaddr_instruct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)
{
perror("connect");
exit(1);
}
while(1){
/*把可读文件描述符的集合清空*/ FD_ZERO(&rfds);
/*把标准输入的文件描述符加入到集合中*/ FD_SET(0, &rfds);
maxfd =0;
/*把当前连接的文件描述符加入到集合中*/ FD_SET(sock_cli, &rfds);
/*找出文件描述符集合中最大的文件描述符*/if(maxfd < sock_cli)
maxfd = sock_cli;
/*设置超时时间*/ tv.tv_sec =5;
tv.tv_usec =0;
/*等待聊天*/ retval =select(maxfd+1, &rfds, NULL, NULL, &tv);
if(retval == -1){
printf("select出错,客户端程序退出\n");
break;
}elseif(retval ==0){
printf("客户端没有任何输入信息,并且服务器也没有信息到来,waiting...\n");
continue;
}else{
/*服务器发来了消息*/if(FD_ISSET(sock_cli,&rfds)){
char recvbuf[BUFFER_SIZE];
int len;
len = recv(sock_cli, recvbuf,sizeof(recvbuf),0);
printf("%s", recvbuf);
memset(recvbuf, 0,sizeof(recvbuf));
}
/*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){
char sendbuf[BUFFER_SIZE];
fgets(sendbuf, sizeof(sendbuf), stdin);
send(sock_cli, sendbuf, strlen(sendbuf),0);//发送memset(sendbuf,0,sizeof(sendbuf));
}
}
}
close(sock_cli);
return0;
}
局域网通过UDP实现服务端和客户端的通信, UDP的服务端不需要执行listen函数和accept函数:
运行下面代码
#include #include #include #include #include #include #include #definePORT_SERV 8888#defineBUFF_LEN 256voidudpserv_echo(ints,structsockaddr* client);int main() {
int s;
struct sockaddr_in addr_serv, addr_clie;
s = socket(AF_INET, SOCK_DGRAM,0);
memset(&addr_serv,0,sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
addr_serv.sin_port = htons(PORT_SERV);
bind(s, (structsockaddr*)&addr_serv,sizeof(addr_serv));
udpserv_echo(s, (structsockaddr*)&addr_clie);
return0;
}voidudpserv_echo(ints,structsockaddr* client) {
int n;
char buff[BUFF_LEN];
int len;
//printf("%p\n",&recvfrom);while(1) {
socklen_t length =sizeof(client);
n = recvfrom(s, buff, BUFF_LEN,0, client, &length);
printf("%s\n", buff);
//strcpy(buff, "nice to see you");sendto(s, buff, n,0, client, len);
}
}
UDP客户端代码, UDP客户端不需要connect函数, 但是执行sendto的时候需要指定 sockfd描述符:
运行下面代码
#include #include #include #include #include #include #definePORT_SERV 8888#defineBUFF_LEN 256voidudpclient_echo(ints,structsockaddr* serv) {
char buff[BUFF_LEN];
intlen =sizeof(*serv);
while(fgets(buff, BUFF_LEN, stdin)!=NULL) {
sendto(s, buff, BUFF_LEN, 0, serv, len);
}
}intmain(intargc ,char** argv) {
int s;
struct sockaddr_in addr_serv;
s = socket(AF_INET, SOCK_DGRAM,0);
memset(&addr_serv,0,sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
//addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);addr_serv.sin_addr.s_addr = inet_addr(argv[1]);
addr_serv.sin_port = htons(PORT_SERV);
udpclient_echo(s, (structsockaddr*)&addr_serv);
return0;
}
获取当前进程的ID:
运行下面代码
#include #include #include intmain(void) {
pid_t pid,ppid;
pid = getpid();
ppid = getppid();
printf("pid is %d;\nppid is %d; \n",pid, ppid);
return0;
}
system语句的使用:
运行下面代码
#include #include intmain(void) {
int ret;
ret = system("ping www.baidu.com");
printf("%d\n", ret);
return0;
}
回到顶部
C++定时器
定时器, 这个是c++的语法, c的标准库中没有定时器:
运行下面代码
#include //printf()#include //pause()#include //signal()#include //memset()#include //struct itimerval, setitimer()staticintcount =0;voidprintMes(int signo)
{
printf("Get a SIGALRM, %d counts!\n", ++count);
}int main()
{
intres =0;
struct itimerval tick;
signal(SIGALRM, printMes);
memset(&tick,0,sizeof(tick));
//Timeout to run first timetick.it_value.tv_sec =1;
tick.it_value.tv_usec =0;
//After first, the Interval time for clocktick.it_interval.tv_sec =1;
tick.it_interval.tv_usec =0;
setitimer(ITIMER_REAL, &tick, NULL);
//if(setitimer(ITIMER_REAL, &tick, NULL) < 0)
//printf("Set timer failed!\n");
//When get a SIGALRM, the main process will enter another loop for pause()while(1)
{
}
return0;
}
select的使用,通过select可以实现定时器:
运行下面代码
staticvoidsleep_ms(unsignedint secs){
struct timeval tval;
tval.tv_sec=secs/1000;
tval.tv_usec=(secs*1000)%1000000;
select(0,NULL,NULL,NULL,&tval);
}
回到顶部
select异步代码
通过select,实现socket可读或者可写的时候,然后再搞事情:
运行下面代码
#include #include #include #include int main() {
while(1) {
fd_set rd;
struct timeval tv;
int err;
FD_ZERO(&rd);
FD_SET(0, &rd);
tv.tv_sec =5;
tv.tv_usec =0;
err =select(1, &rd, NULL, NULL, &tv);
if(err == -1) {
perror("select error()\n");
}elseif(err ==0) {
printf("no data is avaliable now\n");
}else{
if(FD_ISSET(0, &rd)) {
charbuf[1024];
fgets(buf, sizeof(buf), stdin);
printf("%s",buf);
}
}
}
return0;
}
回到顶部
pthead多线程
没有参数的多线程 ,假设文件名字为:ph.c ,那么要通过 gcc ph.c -o ph -w -lphread ,进行编译:
运行下面代码
#include #include #include void*pfn() {
printf("run\n");
}voidmain(intargc ,char*argv[] ) {
pthread_t pid, pid2;
pthread_create(&pid, NULL, pfn, NULL);
pthread_join(pid, NULL);
}
pthead多线程编程, 使用pthead实现子程, 并给子程传递参数:
运行下面代码
#include #include #include #include #include #include void* start(void* args) {
printf("sub thread ; the args is %d\n", *((int*)args));
return NULL;
}intmain(void) {
pthread_t pt;
intret = -1;
inttimes =3;
intrun =2;
ret = pthread_create(&pt, NULL, start, &run);
if(ret !=0) {
printf("create error\n");
return1;
}
usleep(1);
printf("main thread\n");
pthread_join(pt, NULL);
return0;
}
获取指定网卡的MAC地址和IP:
运行下面代码
#include #include #include #include #include #include #include #include #include #include #include #include #include voidgetMac(char*MAC,char*str) {
charifPath[256]="/sys/class/net/";//默认网卡路径 strcat(ifPath , str);
strcat(ifPath ,"/address");
//打开这个设备FILE *ff = fopen(ifPath,"r");
fread(MAC,1,17, ff);
fclose(ff);
}
//根据网卡获取ip的通用函数voidgetIp(unsignedchar*ip,char*itf) {
int fd;
struct ifreq ifr;
in_addr tIP ;
fd = socket(AF_INET, SOCK_DGRAM,0);//using ioctl get IP addressifr.ifr_addr.sa_family = AF_INET;
strcpy(ifr.ifr_name , (char*)itf);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
tIP =((structsockaddr_in *)&ifr.ifr_addr)->sin_addr;
memcpy((char*)ip , &tIP ,sizeof(in_addr));
printf("ip is %s", inet_ntoa(tIP));
}intmain(intargc,char*argv[]) {
struct sockaddr_ll device;
charNetInterface[10];
strcpy(NetInterface, argv[1]);
intindex = if_nametoindex ((constchar*)NetInterface);
printf("index is %d\n", index);
//get MAC, 要设置初始值charMAC[18]={0};
charend[] ="0";
getMac(MAC, argv[1]);
printf("%s\n", MAC);
unsigned charip[4];
getIp(ip, argv[1]);
printf("\n");
return0;
}
C, fork语句的使用, fork返回值为0时说明运行在拷贝线程中:
运行下面代码
#include #include #include #include int main() {
pid_t pid;
pid = fork();
if( -1== pid ) {
printf("error \n");
}elseif( pid ==0 ) {
printf(" fork value %d ; parent id : %d ; fork id : %d\n ", pid, getppid(), getpid());
}else{
printf(" run in parent scope, pid is %d \n", getpid());
}
return0;
}
通过使用fork,可以简化服务端的代码, 局域网聊天服务端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include constintMAX_LINE =2048;constintPORT =6000;constintBACKLOG =10;constintLISTENQ =6666;constintMAX_CONNECT =20;int main() {
struct sockaddr_in serAddr, cliAddr;
int listenFd, connFd;
pid_t childPid;
char buf[MAX_LINE];
socklen_t client;
listenFd = socket(AF_INET, SOCK_STREAM,0);
if(listenFd <0){
perror("socket error");
exit(1);
}
bzero(&serAddr,sizeof(serAddr));
serAddr.sin_family = AF_INET;
serAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serAddr.sin_port = htons(PORT);
if(bind(listenFd, (structsockaddr*)&serAddr,sizeof(serAddr)) <0) {
perror("bind error");
exit(1);
};
if(listen(listenFd, LISTENQ) <0) {
perror("listen error");
exit(1);
};
printf("data");
while(true) {
client =sizeof(cliAddr);
connFd = accept(listenFd, (structsockaddr*)&cliAddr, &client);
if(connFd <0) {
perror("accept error");
exit(1);
}
childPid =fork();
if(childPid ==0) {
close(listenFd);
char buf[MAX_LINE];
while(read(connFd, buf, MAX_LINE) >0) {
printf("data is %s", buf);
memset(buf, 0,sizeof(buf));
};
}
}
close(listenFd);
return0;
}
客户端代码:
运行下面代码
#include #include #include #include #include #include #include #include #include #include constintMAX_LINE =2048;constintPORT =6000;constintBACKLOG =10;constintLISTENQ =6666;constintMAX_CONNECT =20;intmain(intargc ,char**argv) {
int sockFd;
struct sockaddr_in serAddr;
if( argc !=2) {
perror("args error");
exit(1);
}
sockFd = socket(AF_INET, SOCK_STREAM,0);
if(sockFd <0) {
perror("socket error");
exit(1);
}
bzero(&serAddr,sizeof(serAddr));
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
printf("%s",argv[0]);
//serAddr.sin_addr.s_addr = inet_addr(argv[1]);if(inet_pton(AF_INET , argv[1] , &serAddr.sin_addr) <0)
{
printf("inet_pton error for %s\n",argv[1]);
exit(1);
}
if(connect(sockFd, (structsockaddr*)&serAddr,sizeof(serAddr)) <0) {
perror("connect error");
exit(1);
};
char sendLine[MAX_LINE];
while(fgets(sendLine, MAX_LINE, stdin)!=NULL) {
write(sockFd, sendLine, strlen(sendLine));
}
close(sockFd);
return0;
}
socket服务端:
运行下面代码
#include #include #include #include #include #include #include #defineQUEUE 10#defineSIZE 256int main() {
//sock fd int fd;
struct sockaddr_in saddr, caddr;
fd = socket(AF_INET, SOCK_STREAM,0);
if( fd<0 ){
perror("socket error");
exit(1);
}
bzero(&saddr ,sizeof(saddr));
bzero(&caddr ,sizeof(caddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(2000);
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
//bind intbfd = bind(fd, (structsockaddr *)&saddr,sizeof(saddr));
if( bfd<0 ){
perror("bind error");
exit(1);
}
//listenintlfd = listen(fd, QUEUE);
if( lfd<0 ){
perror("listen error");
exit(1);
}
//acceptsocklen_t len =sizeof(caddr);
intconn = accept(fd, (structsockaddr *)&caddr, &len);
if(conn <0){
perror("conn error");
exit(1);
}
char buf[SIZE];
while(read(conn, buf, SIZE) >0) {
//readprintf("%s", buf);
bzero(buf, SIZE);
}
close(fd);
return0;
}
socket客户端:
运行下面代码
#include #include #include #include #include #include #include #include #defineSIZE 256int main() {
int fd;
fd = socket(AF_INET, SOCK_STREAM,0);
struct sockaddr_in saddr;
bzero(&saddr,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(2000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int conn;
conn = connect(fd, (structsockaddr*)&saddr,sizeof(saddr));
if( conn<0 ) {
perror("error");
exit(1);
}
char buf[SIZE];
while(fgets(buf, SIZE, stdin)!=NULL) {
printf("%s", buf);
write(fd, buf, SIZE);
bzero(buf, SIZE);
}
return0;
}