您的位置:首页 > 理论基础 > 计算机网络

linux下c语言tcp通信

2015-09-26 12:38 831 查看
TCP/IP 协议组:

应用层 (FTP / SMTP / HTTP)

传输层 (TCP / UDP)

网络层 (IP ICMP IGMP)

物理层(网络接口层、链路层) (以太网、令牌环网、FDDI)

实例:

服务端

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#define SERVERPORT 3333
#define BACKLOG 10
int main(int argc, char const *argv[])
{
int sockfd,client_fd;
int sin_size;
char str[]="connected success";
struct sockaddr_in my_addr,remote_addr;
//socket creat
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket error");exit(1);
}
//bzero clean
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVERPORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
// bzero(&(my_addr.sin_zero),8);
//可以在这里bzero只清零sin_zero
// 将套接字绑定到服务器的网络地址上
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
perror("bind error");exit(1);
}
//监听客户端连接请求
if (listen(sockfd,BACKLOG)==-1)
{
perror("listen error");exit(1);
}

while(1){
sin_size=sizeof(struct sockaddr_in);
// 等待客户端连接请求到达
if ((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1)
{
perror("accept error");continue;
}
printf("received ip:%s\n",inet_ntoa(remote_addr.sin_addr));
if (!fork())//创建子进程
{	//发送信息
if (send(client_fd,str,strlen(str),0)==-1)
{
perror("send error");close(client_fd);exit(0);
}
while(1){//循环发送
scanf("%s",str);//服务端输入,然后发送。
// fgets(str,80,stdin);
if(strncmp(str,"exit",4)==0)
{
printf("recevice stop ,ending....\n");
close(client_fd);exit(0);
}//发送信息
if (send(client_fd,str,strlen(str),0)==-1)
{
perror("send error");close(client_fd);exit(0);
}
}
}close(client_fd);
}
close(sockfd);
exit(0);
}
客户端

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100 /*每次最大数据传输量 */
int main(int argc, char const *argv[])
{
int sockfd,recvbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if (argc<2)
{
printf("input ip and port\n");exit(1);
}
if((host=gethostbyname(argv[1]))==NULL) {
herror("gethostbyname出错!");
exit(1);
}
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket error");exit(1);
}
bzero(&serv_addr,sizeof(struct sockaddr_in));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
// bzero(&(serv_addr.sin_zero),8);
//connect server
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)
{
perror("connect error");exit(1);
}//获取发来的字节数
if((recvbytes=recv(sockfd,buf,MAXDATASIZE,0))==-1)
{
perror("recv error");exit(1);
}
buf[recvbytes]='\0';
printf("Received:%s\n", buf);
//connected after
while(1){//循环获取
if((recvbytes=recv(sockfd,buf,MAXDATASIZE,0))==-1)
{
perror("recv error");exit(1);
}
if (!recvbytes)
{
close(sockfd);
exit(0);
}
buf[recvbytes]='\0';
printf("Received:%s\n", buf);
}
close(sockfd);
exit(0);
}

注意:

1、客户端.sin_addr和服务端的.sin_addr.s_addr配置。

2、域名的解析和直接输入ip。

使用:

server:./tcps执行

client:./tcpc 192.168.1.x执行

如果有多个客户端连接,则服务端传过去的数据,会先给第一个连接的,

后面连接的要等待上一次连接的进程结束。

struct sockaddr与struct sockaddr_in的区别和联系

www.cnblogs.com/hnrainll/archive/2011/07/18/2109375.html
http://blog.csdn.net/angle0615303/article/details/7657267
参考:
http://blog.csdn.net/piaojun_pj/article/details/5920888 http://www.kuqin.com/networkprog/20080512/8361.html http://www.cnblogs.com/dolphinX/p/3460545.html http://blog.chinaunix.net/uid-20767210-id-1849786.html http://www.cnblogs.com/RascallySnake/archive/2012/01/04/2312564.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: