函数介绍:
int socket(int domain, int type, int protocol);
DESCRIPTION
socket() creates an endpoint for communication and returns a descriptor.
Name Purpose Man page
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK Appletalk ddp(7)
AF_PACKET Low level packet interface packet(7)
RETURN VALUE
On success, a file descriptor for the new socket is returned. On error, -1 is
returned, and errno is set appropriately.
在linux环境下,结构体struct sockaddr_in在/usr/include/netinet/in.h中定义,具体如下:
/* Structure describing an Internet socket address. */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
/* 字符数组sin_zero[8]的存在是为了保证结构体struct sockaddr_in的大小和结构体struct sockaddr的大小相等 */
};
struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。
connect函数介绍:
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
DESCRIPTION
The connect() system call connects the socket referred to by the file descriptor
sockfd to the address specified by addr. The addrlen argument specifies the size
of addr. The format of the address in addr is determined by the address space of
the socket sockfd; see socket(2) for further details.
If the socket sockfd is of type SOCK_DGRAM then addr is the address to which data-
grams are sent by default, and the only address from which datagrams are received.
If the socket is of type SOCK_STREAM or SOCK_SEQPACKET, this call attempts to make
a connection to the socket that is bound to the address specified by addr.
RETURN VALUE
If the connection or binding succeeds, zero is returned. On error, -1 is
int socket(int domain, int type, int protocol);
DESCRIPTION
socket() creates an endpoint for communication and returns a descriptor.
Name Purpose Man page
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK Appletalk ddp(7)
AF_PACKET Low level packet interface packet(7)
RETURN VALUE
On success, a file descriptor for the new socket is returned. On error, -1 is
returned, and errno is set appropriately.
在linux环境下,结构体struct sockaddr_in在/usr/include/netinet/in.h中定义,具体如下:
/* Structure describing an Internet socket address. */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
/* 字符数组sin_zero[8]的存在是为了保证结构体struct sockaddr_in的大小和结构体struct sockaddr的大小相等 */
};
struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。
connect函数介绍:
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
DESCRIPTION
The connect() system call connects the socket referred to by the file descriptor
sockfd to the address specified by addr. The addrlen argument specifies the size
of addr. The format of the address in addr is determined by the address space of
the socket sockfd; see socket(2) for further details.
If the socket sockfd is of type SOCK_DGRAM then addr is the address to which data-
grams are sent by default, and the only address from which datagrams are received.
If the socket is of type SOCK_STREAM or SOCK_SEQPACKET, this call attempts to make
a connection to the socket that is bound to the address specified by addr.
RETURN VALUE
If the connection or binding succeeds, zero is returned. On error, -1 is
returned, and errno is set appropriately.
注意:在编译的时候要加-pthread选项
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
static usage(const char* proc)
{
printf("usage:%s[ip][port]\n",proc);
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
usage(argv[0]);
exit(1);
}
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket");
return 2;
}
struct sockaddr_in remote;
remote.sin_family=AF_INET;
remote.sin_port=htons(atoi(argv[2]));
remote.sin_addr.s_addr=inet_addr(argv[1]);
if(connect(sock,(struct sockaddr*)&remote,sizeof(remote))<0)
{
perror("connect");
return 3;
}
char buf[1024];
while(1)
{
memset(buf,'\0',sizeof(buf));
printf("please enter:");
fflush(stdout);
ssize_t _s=read(0,buf,sizeof(buf)-1);
if(_s>0)
{
buf[_s-1]='\0';
write(sock,buf,strlen(buf));
_s=read(sock,buf,sizeof(buf));
if(_s>0)
{
buf[_s]='\0';
printf("%s\n",buf);
}
}
}
return 0;
}
服务器端:
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<pthread.h>
#include<arpa/inet.h>
#include<sys/socket.h>
static void usage(const char *proc)
{
printf("usage:%s[ip][port]\n",proc);
}
void *thread_run(void *arg)
{
printf("create a new thread\n");
int fd=(int)arg;
char buf[1024];
while(1)
{
memset(buf,'\0',sizeof(buf));
size_t _s =read(fd,buf,sizeof(buf)-1);
if(_s>0)
{
buf[_s]='\0';
printf("client:%s\n",buf);
write(fd,buf,strlen(buf));
}
else if(_s==0)
{
printf("client close...\n");
break;
}
else
{
printf("read error...\n");
break;
}
}
return (void*)0;
}
int main(int argc,char *argv[])
{
if(argc!=3)
{
usage(argv[0]);
exit(1);
}
//create sock
int listen_sock=socket(AF_INET,SOCK_STREAM,0);
if(listen_sock<0)
{
printf("create error,errno:%d %s\n",errno,strerror(errno));
}
struct sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(atoi(argv[2]));
local.sin_addr.s_addr=inet_addr(argv[1]);
//bind
if(bind(listen_sock,(struct sockaddr*)&local,sizeof(local))<0)
{
perror("bind");
return 2;
}
//listen
listen(listen_sock,5);
//accept
struct sockaddr_in peer;
socklen_t len=sizeof(peer);
while(1)
{
int fd=accept(listen_sock,(struct sockaddr*)&peer,&len);
if(fd<0)
{
perror("accept");
return 3;
}
printf("get a new link,socket -> %s:%d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
pthread_t id;
pthread_create(&id,NULL,thread_run,(void*)fd);
pthread_detach(id);
}
return 0;
}