创建步骤:
1、使用socket()函数创建socket;
int socket(int domain, int type, int protocol);
RETURN VALUE
On success, a file descriptor for the new socket is returned.
On error, -1 is returned,
2、使用bind()函数绑定IP地址和端口信息到socket;
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
RETURN VALUE
On success, zero is returned. On error, -1 is returned
3、设置允许的最大连接数,使用函数listen();
int listen(int sockfd, int backlog);
RETURN VALUE
On success, zero is returned. On error, -1 is returned
4、使用函数accept()等待来自客户端的连接请求;
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
RETURN VALUE
On success, return a nonnegative integer that is a descriptor for the accepted socket.
On error, -1 is returned
5、收发数据,用函数recv()、send()/sendto()或者read()、write();
6、通信完毕,关闭网络连接close()。
TCP/IP协议中我们用到的IP是以“.”隔开的十进制数表示如127.1.1.12,
而在套接字的数据结构中使用的是32位的网络字节序的二进制数值。实现两者间转化的函数如下:
#include <arpa/inet.h>
int inet_aton(const char *cp,struct in_addr *inp)
char *inet_ntoa(struct in_addr in)
inet_addr(const char *cp)
// 函数里面a代表ascii ,n 代表network。
// inet_aton是将a.b.c.d形式的IP转换为32位的网络字节序IP,存储在inp指针里面。
// inet_ntoa是将32位网络字节序IP转换为a.b.c.d的格式。
// inet_addr将a.b.c.d形式的IP转化为网络字节序的32位IP
网络传输的数据的方式:大端模式(大端字节序)
主机存储数据的方式不统一,可能是大端模式也可能是小端模式
htons() 把unsigned short类型从主机序转换到网络序
htonl() 把unsigned long类型从主机序转换到网络序
ntohs() 把unsigned short类型从网络序转换到主机序
ntohl() 把unsigned long类型从网络序转换到主机序
32bit的整数(0x01234567)从地址0x100开始
简单TCP server/client:
//TCPserver.c
#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
#define PORT 5678
int main(int argc,char *argv[])
{
int sd,ad;
int err;
int client_addrlen;
char buf[20];
struct sockaddr_in server_addr, client_addr;
sd = socket(AF_INET,SOCK_STREAM,0);
if(sd == -1)
{
printf("creat socket error,errno = %d\n",errno);
return -1;
}
memset(&server_addr,0,sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//32bit IPv4 Address
err = bind(sd ,(struct sockaddr *)&server_addr,sizeof(struct sockaddr));
if(err == -1)
{
printf("bind error,errno is %d\n",errno);
close(sd);
return -1;
}
printf("bind success!\n");
if(listen(sd ,10) == -1)
{
printf("listen error,errno is %d\n",errno);
close(sd);
return -1;
}
printf("listening...\n");
while(1)
{
client_addrlen = sizeof(struct sockaddr);
ad = accept(sd ,(struct sockaddr *)&client_addr,&client_addrlen);
if(ad == -1)
{
printf("accept error,errno is %d\n",errno);
close(sd);
return -1;
}
printf("Catch connect!client IP:%s;PORT:%d\n"
,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
read(ad,&buf,20);
printf("recv from client :%s\n",buf);
close(ad);
}
close(sd);
return 0;
}
//TCP client
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
//#define PORT 5678
//#define IP "127.0.0.1"
int main(int argc,char *argv[])
{
int sockfd;
int err;
int client_addrlen;
char *host;
char buf[20];
int port;
// char buf[20] = "I am client";
if(argc !=3)
{
printf("format error!format: %s address port\n",argv[0]);
return -1;
}
if((host = argv[1])==NULL)
{
printf("please enter true address!\n");
return -1;
}
if((port = atoi(argv[2]))<0)
{
printf("please enter true port!\n");
return -1;
}
struct sockaddr_in server_addr, client_addr;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
printf("creat socket error,errno = %d\n",errno);
return -1;
}
printf("client sockfd is %d\n",sockfd);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(host);
// inet_aton(&IP,&server_addr.sin_addr);
err = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(err==-1)
{
printf("connect error,errno = %d\n",errno);
return -1;
}
printf("connected!Target server IP:%s PORT:%d \n",host,ntohs(server_addr.sin_port));
printf("please enter message:");
fgets(buf,20,stdin);
write(sockfd,&buf,20);
close(sockfd);
return 0;
}
//升级版服务器端
#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<pthread.h>
#define PORT 5678
char ad[20],buf[20];
int i;
struct sockaddr_in server_addr, client_addr;
void *pthread_read(void *arg)
{
while(1)
{
read(ad[(int)arg],buf,20);
printf("client IP:%s, msg:%s\n",inet_ntoa(client_addr.sin_addr),buf);
}
return NULL;
}
int main(int argc,char *argv[])
{
int sd;
int err,err1;
int client_addrlen;
pthread_t ntid[20];
sd = socket(AF_INET,SOCK_STREAM,0);
if(sd == -1)
{
printf("creat socket error,errno = %d\n",errno);
return -1;
}
memset(&server_addr,0,sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//32bit IPv4 Address
err = bind(sd ,(struct sockaddr *)&server_addr,sizeof(struct sockaddr));
if(err == -1)
{
printf("bind error,errno is %d\n",errno);
close(sd);
return -1;
}
printf("bind success!\n");
if(listen(sd ,10) == -1)
{
printf("listen error,errno is %d\n",errno);
close(sd);
return -1;
}
printf("listening...\n");
client_addrlen = sizeof(struct sockaddr);
while(1)
{
ad[i]= accept(sd,(struct sockaddr *)(&client_addr),&client_addrlen);
if(ad[i] == -1)
{
printf("accept error,errno is %d\n",errno);
close(sd);
return -1;
}
printf("Catch connect!IP:%s;PORT:%d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
err1 = pthread_create(&ntid[i],NULL,pthread_read,(void *)i);
if(err1!=0)
{
printf("creat thread error!\n");
close(ad[i]);
}
i++;
}
close(sd);
return 0;
}
//升级版客户端
int main(int argc,char *argv[])
{
int sockfd;
int err;
int client_addrlen;
char *host;
char buf[20];
int port;
if(argc !=3)
{
printf("format error!format: %s address port\n",argv[0]);
return -1;
}
if((host = argv[1])==NULL)
{
printf("please enter true address!\n");
return -1;
}
if((port = atoi(argv[2]))<0)
{
printf("please enter true port!\n");
return -1;
}
struct sockaddr_in server_addr, client_addr;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
printf("creat socket error,errno = %d\n",errno);
return -1;
}
printf("client sockfd is %d\n",sockfd);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(host);
err = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(err==-1)
{
printf("connect error,errno = %d\n",errno);
return -1;
}
printf("connected!Target server IP:%s PORT:%d \n",host,ntohs(server_addr.sin_port));
while(1)
{
printf("please enter message:");
fgets(buf,20,stdin);
write(sockfd,&buf,20);
}
close(sockfd);
return 0;
}