本博文给出了两个socket通信的例子,一个是需要建立链接的,一个是不需要建立链接的。
1.直接上代码:echo_serv.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define EHCO_PORT 8080
#define MAX_CLIENT_NUM 10
int main()
{
int sock_fd;
struct sockaddr_in serv_addr;
int clientfd;
struct sockaddr_in clientAdd;
char buff[101];
socklen_t len;
int n;
//创建socket
sock_fd = socket(AF_INET, SOCK_STREAM,0);
if(sock_fd == -1)
{
perror("create socket error!");
return 0;
}
else
{
printf("Success to create socket %d\n",sock_fd);
}
//设置server地址结构
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(EHCO_PORT);
serv_addr.sin_addr.s_addr = htons(INADDR_ANY);
bzero(&(serv_addr.sin_zero),8);
//把地址和套接字绑定
if(bind(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))!=0)
{
printf("bind address fail! %d\n",errno);
close(sock_fd);
return 0;
}
else
{
printf("Success to bind address!\n");
}
//设置套接字接听
if(listen(sock_fd,MAX_CLIENT_NUM)!=0)
{
perror("listen socket error!\n");
close(sock_fd);
return 0;
}
else
{
printf("Success to listen.\n");
}
//创建新连接对应的套接字
len = sizeof(clientAdd);
clientfd = accept(sock_fd,(struct sockaddr*)&clientAdd,&len);
if(clientfd<=0)
{
perror("accept error!\n");
close(sock_fd);
return 0;
}
//接收用户发来的数据
while((n=recv(clientfd,buff,100,0))>0)
{
buff[n]='\0';
printf("number of receive bytes = %d data = %s\n",n,buff);
//fflush(stdout);
send(clientfd,buff,n,0);
if(strncmp(buff,"quit",4)==0)
break;
}
close(clientfd);
close(sock_fd);
return 0;
}
echo_client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define EHCO_PORT 8080
#define MAX_COMMAND 5
int main()
{
int sock_fd;
struct sockaddr_in serv_addr;
char *buff[MAX_COMMAND]={"abc","def","test","hello","quit"};
char tmp_buf[100];
char send_buf[100];
int n,i,X=500,Y=500;
//
sock_fd = socket(AF_INET, SOCK_STREAM,0);
if(sock_fd == -1)
{
perror("create socket error!");
return 0;
}
else
{
printf("Success to create socket %d\n",sock_fd);
}
//
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(EHCO_PORT);
serv_addr.sin_addr.s_addr = htons(INADDR_ANY);
bzero(&(serv_addr.sin_zero),8);
//
if(-1 == connect(sock_fd, (struct sockaddr*)&serv_addr,sizeof(serv_addr)))
{
perror("connect() error!\n");
close(sock_fd);
return 0;
}
printf("Success connect to server!\n");
//发送数据
/*
for(i=0;i<MAX_COMMAND;i++)
{
send(sock_fd,buff[i],100,0);
n = recv(sock_fd,tmp_buf,100,0);
tmp_buf[n]='\0';
printf("data send:%s receive:%s\n",buff[i],tmp_buf);
if(0==strncmp(tmp_buf,"quit",4))
break;
}
*/
while(1)
{
//n=scanf("%s",send_buf); //scanf函数会考虑空白作为换行符号
printf("***pls send data:");
//gets(send_buf); //gets函数不够安全,因为不考虑缓冲区大小,会覆盖越界部分,蠕虫病毒就是这个原理
//fgets(send_buf,100,stdin);//如果用fgets函数的话,换行符号会保存在字符串中
n=sprintf(send_buf,"X=%d,Y=%d\n",X,Y);
send(sock_fd,send_buf,100,0);
n = recv(sock_fd,tmp_buf,100,0);
tmp_buf[n]='\0';
printf("data send:%s receive:%s\n",send_buf,tmp_buf);
if(0==strncmp(send_buf,"quit",4))
break;
}
close(sock_fd);
return 0;
}
2.不建立链接的例子:客户端向服务端请求当前时间,服务端收到之后,返回时间,结束。
time_serv.c
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<time.h>
#include<string.h>
#define TIME_PORT 9090
#define DATA_SIZE 256
int main()
{
int sock_fd;
struct sockaddr_in local;
struct sockaddr_in from;
int n;
socklen_t fromlen;
char buff[DATA_SIZE];
time_t cur_time;
sock_fd = socket(AF_INET, SOCK_DGRAM,0);
if(sock_fd <=0)
{
perror("create socket error!");
return 0;
}
printf("create socket.");
local.sin_family = AF_INET;
local.sin_port = htons(TIME_PORT);
local.sin_addr.s_addr=INADDR_ANY;
if(0!=bind(sock_fd,(struct sockaddr*)&local,sizeof(local)))
{
perror("bind socket error!");
close(sock_fd);
return 0;
}
printf("Bind socket.");
fromlen = sizeof(from);
printf("waiting request from client...\n");
while(1)
{
n=recvfrom(sock_fd,buff,sizeof(buff),0,(struct sockaddr*)&from, &fromlen);
if(n<=0)
{
perror("recv data!\n");
close(sock_fd);
return 0;
}
buff[n]='\0';
printf("client request: %s\n",buff);
if(0==strncmp(buff,"quit",4))
break;
if(0==strncmp(buff,"time",4))
{
cur_time = time(NULL);
strcpy(buff,asctime(gmtime(&cur_time)));
sendto(sock_fd,buff,sizeof(buff),0,(struct sockaddr*)&from,fromlen);
}
}
close(sock_fd);
}
time_client.c
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<time.h>
#include<string.h>
#define TIME_PORT 9090
#define DATA_SIZE 256
int main()
{
int sock_fd;
struct sockaddr_in serv;
int n;
socklen_t servlen;
char buff[DATA_SIZE];
sock_fd = socket(AF_INET, SOCK_DGRAM,0);
if(sock_fd <=0)
{
perror("create socket error!");
return 0;
}
printf("create socket.");
serv.sin_family = AF_INET;
serv.sin_port = htons(TIME_PORT);
serv.sin_addr.s_addr=INADDR_ANY;
servlen = sizeof(serv);
//
strcpy(buff,"time");
if(-1==sendto(sock_fd,buff,sizeof(buff),0,(struct sockaddr*)&serv,servlen))
{
perror("send data");
close(sock_fd);
return 0;
}
printf("send time request\n");
n=recvfrom(sock_fd,buff,sizeof(buff),0,(struct sockaddr*)&serv,&servlen);
if(n<=0)
{
perror("recv data!\n");
close(sock_fd);
return 0;
}
buff[n]='\0';
printf("time from server:%s",buff);
strcpy(buff,"quit");
if(-1==sendto(sock_fd,buff,sizeof(buff),0,(struct sockaddr*)&serv,servlen))
{
perror("send data");
close(sock_fd);
return 0;
}
printf("send quit command\n");
close(sock_fd);
return 0;
}
编译的话,可以使用之前写的Makefile文件,生成同名的可执行文件。