原创文章,转载请注明转载字样和出处,谢谢!
这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到client的连接后,发送数据给client;client在接受到数据后打印出来,然后关闭。程序里有具体的说明,当中对具体的结构体和函数的实现能够參考其它资料。
程序说明: 这里server的port号和ip地址使用固定的设置,移植时能够依据详细情况更改,能够改写为參数传递更好,这里为了方便,使用固定的。
移植时服务端能够不用更改,编译后可直接执行;client将ip改为server的地址,然后编译执行。能够使用netstat 进行查看对应的执行状态。
/************************************* 文件名称: server.c linux 下socket网络编程简例 - 服务端程序 serverport设为 0x8888 (port和地址可依据实际情况更改,或者使用參数传入) server地址设为 192.168.1.104 作者:kikilizhm#163.com (将#换为@) */ #include <stdlib.h> #include <sys/types.h> #include <stdio.h> #include <sys/socket.h> #include <linux/in.h> #include <string.h> int main() { int sfp,nfp; /* 定义两个描写叙述符 */ struct sockaddr_in s_add,c_add; int sin_size; unsigned short portnum=0x8888; /* 服务端使用端口 */ printf("Hello,welcome to my server ! "); sfp = socket(AF_INET, SOCK_STREAM, 0); if(-1 == sfp) { printf("socket fail ! "); return -1; } printf("socket ok ! "); /* 填充serverport地址信息,以便以下使用此地址和port监听 */ bzero(&s_add,sizeof(struct sockaddr_in)); s_add.sin_family=AF_INET; s_add.sin_addr.s_addr=htonl(INADDR_ANY); /* 这里地址使用全0,即全部 */ s_add.sin_port=htons(portnum); /* 使用bind进行绑定port */ if(-1 == bind(sfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))) { printf("bind fail ! "); return -1; } printf("bind ok ! "); /* 開始监听对应的port */ if(-1 == listen(sfp,5)) { printf("listen fail ! "); return -1; } printf("listen ok "); while(1) { sin_size = sizeof(struct sockaddr_in); /* accept服务端使用函数,调用时即进入堵塞状态,等待用户进行连接,在没有client进行连接时,程序停止在此处, 不会看到后面的打印,当有client进行连接时,程序立即运行一次,然后再次循环到此处继续等待。 此处accept的第二个參数用于获取client的port和地址信息。 */ nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size); if(-1 == nfp) { printf("accept fail ! "); return -1; } printf("accept ok! Server start get connect from %#x : %#x ",ntohl(c_add.sin_addr.s_addr),ntohs(c_add.sin_port)); /* 这里使用write向client发送信息,也能够尝试使用其它函数实现 */ if(-1 == write(nfp,"hello,welcome to my server ",32)) { printf("write fail! "); return -1; } printf("write ok! "); close(nfp); } close(sfp); return 0; }
/************************************* 文件名称: client.c linux 下socket网络编程简例 - client程序 serverport设为 0x8888 (port和地址可依据实际情况更改,或者使用參数传入) server地址设为 192.168.1.104 作者:kikilizhm#163.com (将#换为@) */ #include <stdlib.h> #include <sys/types.h> #include <stdio.h> #include <sys/socket.h> #include <linux/in.h> #include <string.h> int main() { int cfd; /* 文件描写叙述符 */ int recbytes; int sin_size; char buffer[1024]={0}; /* 接受缓冲区 */ struct sockaddr_in s_add,c_add; /* 存储服务端和本端的ip、port等信息结构体 */ unsigned short portnum=0x8888; /* 服务端使用的通信端口,能够更改,需和服务端同样 */ printf("Hello,welcome to client ! "); /* 建立socket 使用因特网,TCP流传输 */ cfd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == cfd) { printf("socket fail ! "); return -1; } printf("socket ok ! "); /* 构造server端的ip和port信息,详细结构体能够查资料 */ bzero(&s_add,sizeof(struct sockaddr_in)); s_add.sin_family=AF_INET; s_add.sin_addr.s_addr= inet_addr("192.168.1.104"); /* ip转换为4字节整形,使用时须要依据服务端ip进行更改 */ s_add.sin_port=htons(portnum); /* 这里htons是将short型数据字节序由主机型转换为网络型,事实上就是 将2字节数据的前后两个字节倒换,和相应的ntohs效果、实质同样,仅仅只是名字不同。htonl和ntohl是 操作的4字节整形。将0x12345678变为0x78563412,名字不同,内容两两同样,普通情况下网络为大端, PPC的cpu为大端,x86的cpu为小端,arm的能够配置大小端,须要保证接收时字节序正确。 */ printf("s_addr = %#x ,port : %#x ",s_add.sin_addr.s_addr,s_add.sin_port); /* 这里打印出的是小端 和我们平时看到的是相反的。 */ /* client连接server,參数依次为socket文件描写叙述符,地址信息,地址结构大小 */ if(-1 == connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))) { printf("connect fail ! "); return -1; } printf("connect ok ! "); /*连接成功,从服务端接收字符*/ if(-1 == (recbytes = read(cfd,buffer,1024))) { printf("read data fail ! "); return -1; } printf("read ok REC: "); buffer[recbytes]=' '; printf("%s ",buffer); getchar(); /* 此句为使程序暂停在此处,能够使用netstat查看当前的连接 */ close(cfd); /* 关闭连接,本次通信完毕 */ return 0; }
执行截图: