http://haibor1x.blog.163.com/blog/static/763407200751052458572/
一个linux UDP网络通讯的例子源代码(server、client方式)
服务器端代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int sock;
//sendto中使用的对方地址
struct sockaddr_in toAddr;
//在recvfrom中使用的对方主机地址
struct sockaddr_in fromAddr;
int recvLen;
unsigned int addrLen;
char recvBuffer[128];
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sock < 0)
{
printf("创建套接字失败了.\r\n");
exit(0);
}
memset(&fromAddr, 0, sizeof(fromAddr));
fromAddr.sin_family = AF_INET;
fromAddr.sin_addr.s_addr = htonl(INADDR_ANY);
fromAddr.sin_port = htons(4000);
if(bind(sock, (struct sockaddr *)&fromAddr, sizeof(fromAddr)) < 0)
{
printf("bind() 函数使用失败了.\r\n");
close(sock);
exit(1);
}
while(1)
{
addrLen = sizeof(toAddr);
if((recvLen = recvfrom(sock, recvBuffer, 128, 0, (struct sockaddr *)&toAddr, &addrLen)) < 0)
{
printf("()recvfrom()函数使用失败了.\r\n");
close(sock);
exit(1);
}
if(sendto(sock, recvBuffer, recvLen, 0, (struct sockaddr *)&toAddr, sizeof(toAddr)) != recvLen)
{
printf("sendto fail\r\n");
close(sock);
exit(0);
}
return 0;
}
}
客户端代码
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- int main(int argc, char *argv[])
- {
- if(argc < 2)
- {
- printf("请输入要传送的内容.\r\n");
- exit(0);
- }
- int sock;
- //sendto中使用的对方地址
- struct sockaddr_in toAddr;
- //在recvfrom中使用的对方主机地址
- struct sockaddr_in fromAddr;
- unsigned int fromLen;
- char recvBuffer[128];
- sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if(sock < 0)
- {
- printf("创建套接字失败了.\r\n");
- exit(1);
- }
- memset(&toAddr, 0, sizeof(toAddr));
- toAddr.sin_family = AF_INET;
- toAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
- toAddr.sin_port = htons(4000);
- if(sendto(sock, argv[1], strlen(argv[1]), 0, (struct sockaddr *)&toAddr, sizeof(toAddr)) != strlen(argv[1]))
- {
- printf("sendto() 函数使用失败了.\r\n");
- close(sock);
- exit(1);
- }
- fromLen = sizeof(fromAddr);
- if(recvfrom(sock, recvBuffer, 128, 0, (struct sockaddr *)&fromAddr, &fromLen) < 0)
- {
- printf("()recvfrom()函数使用失败了.\r\n");
- close(sock);
- exit(1);
- }
- printf("recvfrom() result:%s\r\n", recvBuffer);
- close(sock);
- return 0;
- }
http://bbs.csdn.net/topics/310080001
Linux 进程间通信 事例
用于进程间通信的socket主要是指unix domain socket; 它用到这样一个地址结构
struct sockaddr_un; 这个结构在<sys/un.h>头文件中;有两个主要成员
sun_family和sun_path; sun_family可以是AF_UNIX或者AF_LOCALE;sun_path是一个文件名,一般用绝对路径; 这儿给个用unix domain socket的小例子;这个例子用的就是UDP形式;直接上代码
//header.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <signal.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/un.h> //for unix domain socket
#include <pthread.h>
#define BUFSIZE 1024
#define SERVPORT 5000
//for unix domain socket
#define SOCKET_PATH "/tmp/serverpath"
//error
#ifdef __cplusplus
extern
"C"
{
#endif
void
error(
const
char
*fmt,...){
char
buf[BUFSIZE];
va_list
ptr;
memset
(buf,0,BUFSIZE);
va_start
(ptr,fmt);
vsnprintf(buf,BUFSIZE,fmt,ptr);
va_end
(ptr);
fprintf
(stderr,
"%s\n"
,buf);
exit
(EXIT_FAILURE);
}
#ifdef __cplusplus
}
#endif
|
//unixdomain.c 服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
/*
unix domain socket: designed for interprocess communication
key system calls: socket/bind/connect/listen/accept
key structure: struct sockaddr_un
Author: hittlle
purpose: Demo of UNIX Domain Socket
Program Name: DomainServer
*/
#include "header.h"
int
main(
int
argc,
char
**argv){
int
listenFd, clientFd;
struct
sockaddr_un servAddr, clientAddr;
socklen_t socklen;
char
buf[BUFSIZE];
bzero(buf, BUFSIZE);
bzero(&servAddr,
sizeof
(servAddr));
//set address
servAddr.sun_family = AF_UNIX;
//AF_LOCALE is also OK
strcpy
(servAddr.sun_path, SOCKET_PATH);
unlink(SOCKET_PATH);
if
((listenFd = socket(AF_UNIX, SOCK_DGRAM,0)) < 0)
error(
"%s"
,
strerror
(
errno
));
if
(bind(listenFd, (
struct
sockaddr*)&servAddr,
sizeof
(servAddr)) < 0){
close(listenFd);
error(
"%s"
,
strerror
(
errno
));
}
while
(1){
if
(recvfrom(listenFd,buf,BUFSIZE,0,(
struct
sockaddr*)&clientAddr,&socklen) > 0)
write(STDOUT_FILENO,buf,
sizeof
(buf));
}
return
0;
}
|
//unixclient.c 客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#include "header.h"
int
main(
int
argc,
char
**argv){
int
sockfd;
struct
sockaddr_un servaddr;
socklen_t socklen =
sizeof
(
struct
sockaddr_un);
char
buf[BUFSIZE] =
"This is a test message here......Demo of Domain Socket\n"
;
bzero(&servaddr,
sizeof
(servaddr));
servaddr.sun_family = AF_UNIX;
strcpy
(servaddr.sun_path, SOCKET_PATH);
if
((sockfd = socket(AF_UNIX,SOCK_DGRAM,0)) < 0)
error(
"%s"
,
strerror
(
errno
));
sendto(sockfd,buf,
sizeof
(buf),0, (
struct
sockaddr*)&servaddr,socklen);
close(sockfd);
return
0;
}
这只是一个小例子,别拍砖
|
用于进程间通信的socket主要是指unix domain socket; 它用到这样一个地址结构
struct sockaddr_un; 这个结构在<sys/un.h>头文件中;有两个主要成员
sun_family和sun_path; sun_family可以是AF_UNIX或者AF_LOCALE;sun_path是一个文件名,一般用绝对路径;
主要是这个数据结构的sun_path,填对了就ok
http://www.iteye.com/topic/1113587
Linux下Socket通信(IPC)
1、Linux下的Socket通信是一种基于文件的IPC通信,也可以是基于其他设备的IPC通信。它可以在本机内不同进程间实现通信,也可以在实现不同主机之间的通信。
2、Socket是一种进程间通信模式:
对等模式(P2P):一对一:UDP
客户服务器模式(C/S):一对多:TCP
3、基本创建步骤
(1)通过socket()函数创建socket
(2)通过bind函数绑定socket于设备地址
(3)进行读写操作read/recv/recvfrom write/send/sendto
(4)close方法关闭套接字
4、下面是其中用到的一些函数的用法及说明
(1)socket函数
int socket(int domain,int type, int protocol)
domain:地址族 IF_INET与底层内核通信(原生数据包)
type:通信的数据格式
protocol:传递数的含义
通信的数据类型:
SOCK_STREAM:字节流(一对多)
SOCK_DGRAM:字节包(一对一)
SOCK_RAW:硬件层的原生数据包
通信的协议:
0:默认协议:地址族+数据格式=唯一决定协议
指定协议 IPPROTO_TCP
IPPROTO_UDP
IPPROTO_IP
IPPROTO_ICMP
IPPROTO_IGMP
(2)bind函数
把socket绑定到一个通信地址
int bind(int sockfd,const struct sockaddr* addr,socklen_t len)
sockfd:绑定地址的socket
addr:地址
len:地址内存长度
返回:成功是0,失败是-1
(3)recvfrom函数
如果想返回数据发送者的地址,则使用recvfrom.
int recvfrom(int fd,
void *buf,
size_t len,
int flag,
struct sockaddr*addr,//返回数据发送者的地址) ssocklen_t *l);//输入返回地址缓冲长度,返回实际发送者的地址长度
(4)write/send/sendto函数
int sendto(int fd,//发送socket
const void *buf,//发送的数据
size_t len,//发送数据的长度
int flag,//发送数据的方式,建议为0
const struct sockaddr *addr,//数据 发往的目的地址
socklen_t l);//地址长度
返回:
-1:发送失败
否则就是发送的字节数。
代码如下:
test1.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main(void)
- {
- //create socket
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- if(fd==-1)
- {
- perror("socket\n");
- exit(-1);
- }
- printf("socket fd=%d\n",fd);
- //build connection address
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(6666);
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- int r;
- r = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
- if(r==-1)
- {
- perror("bind");
- close(fd);
- exit(-1);
- }
- printf("bind address successful!\n");
- //accept or send message
- char buf[255];
- struct sockaddr_in from;
- socklen_t len;
- len = sizeof(from);
- while(1)
- {
- r = recvfrom(fd,buf,sizeof(buf)-1,0,(struct sockaddr*)&from,&len);
- if(r>0)
- {
- buf[r]=0;
- printf("The message from %s is:%s\n",inet_ntoa(from.sin_addr),buf);
- }
- else
- {
- break;
- }
- }
- //close socket
- close(fd);
- return 0;
- }
test2.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main(void)
- {
- //create socket
- int fd = socket(AF_INET,SOCK_DGRAM,0);
- if(fd==-1)
- {
- perror("socket");
- exit(-1);
- }
- printf("create socket OK!\n");
- //create an send address
- struct sockaddr_in addr={};
- addr.sin_family = AF_INET;
- addr.sin_port = htons(6666);
- addr.sin_addr.s_addr=inet_addr("127.0.0.1");
- //send the message to the specify address
- int r;
- char buf[255];
- while(1)
- {
- r = read(0,buf,sizeof(buf)-1);
- if(r<=0)
- break;
- sendto(fd,buf,r,0,(struct sockaddr*)&addr,sizeof(addr));
- }
- //close socket
- close(fd);
- return 0;
- }
运行结果如下:(先运行test1.o,然后运行test2.o,在test2.c运行后输入内容,在test1.c所在终端中就会显示信息)
http://www.ibm.com/developerworks/cn/linux/l-socket-ipc/
在 Linux 上实现基于 Socket 的多进程实时通信
套接口(Socket)为目前Linux上最为广泛使用的一种的进程间通信机制,与其他的Linux通信机制不同之处在于除了它可用于单机内的进程间通信以外,还可用于不同机器之间的进程间通信。但是由于Socket本身不支持同时等待和超时处理,所以它不能直接用来多进程之间的相互实时通信。
本文提出一个基于Socket的多进程之间通信的实现方法。原理是建立一个进程专门用来做为通信服务器(server)来中转各个进程之间的通信。它首先启动一个用来监视连接要求的listening Socket,并把它的描述(Descriptor)号加入到一个事先定义好的fd_set的集合中,这个fd_set的集合用来存放listening Socket和后来生成的通信Socket的描述号。Server运用system call select来实时检查是否有数据到达这个集合中的任何一个socket,如果有数据到达listening Socket,则这一定是客户端发起的连接请求,于是生成一个新的通信Socket与该客户端连接,将生成的Socket描述号加入到fd_set的集合中,将客户端的ID号和与之对应的Socket的描述号记录在ID登记表中。如果有数据到达某个通信Socket,则这一定是某个客户端发起的通信请求,读出数据并取出收信客户端ID号,在ID登记表中找到与之对应的Socket描述号,将数据通过对应Socket传送到收信客户端。
其他各进程作为客户端(client)。客户端的动作是首先建立通信Socket连接服务器端,然后通过通信Socket进行送信和收信。
下面给出具体的程序实现和说明,
首先给出Server端的程序,在这里假设有两个客户端要进行实时通信,ClientA向ClientB发送字符1,ClientB向ClientA发送字符2。
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <sys/un.h> #include <sys/time.h> #include <sys/ioctl.h> #include <unistd.h> #include <netinet/in.h> int main() { int rcd ; struct sockaddr_un server_sockaddr ; int backlog ; ushort ci ; int watch_fd_list[3] ; fd_set catch_fd_set ; fd_set watchset ; int new_cli_fd ; int maxfd; int socklen ,server_len; struct sockaddr_un cli_sockaddr ; struct { char module_id ; /* Module ID */ int cli_sock_fd ; /* Socket ID */ } cli_info_t[2] ; for (ci=0;ci<=1;ci++) cli_info_t[ci].cli_sock_fd=-1; for (ci=0;ci<=2;ci++) watch_fd_list[ci]=-1; int server_sockfd,client_sockfd; server_sockfd = socket( AF_UNIX, SOCK_STREAM, 0 ) ; server_sockaddr.sun_family = AF_UNIX ; strcpy( server_sockaddr.sun_path, "server_socket" ) ; server_len=sizeof(server_sockaddr); rcd = bind( server_sockfd, ( struct sockaddr * )&server_sockaddr, server_len ) ; backlog = 5 ; rcd = listen( server_sockfd, backlog ) ; printf("SERVER::Server is waitting on socket=%d \n",server_sockfd); watch_fd_list[0]=server_sockfd; FD_ZERO( &watchset ) ; FD_SET( server_sockfd, &watchset ) ; maxfd=watch_fd_list[0]; |
在上面的程序中,Server生成listening Socket(server_sockfd),初始化Socket监视集合(watchset),并将listening Socket放入Socket监视集合中。
while (1){ char ch; int fd; int nread; catch_fd_set=watchset; rcd = select( maxfd+1, &catch_fd_set, NULL, NULL, (struct timeval *)0 ) ; |
在上面的程序中,Server运用系统调用函数 select来实时检查是否有数据到达Socket监视集合中的任何一个socket。
if ( rcd < 0 ) { printf("SERVER::Server 5 \n"); exit(1); } if ( FD_ISSET( server_sockfd, &catch_fd_set ) ) { socklen = sizeof( cli_sockaddr ) ; new_cli_fd = accept( server_sockfd, ( struct sockaddr * ) &( cli_sockaddr ), &socklen ) ; printf(" SERVER::open communication with Client %s on socket %d\n", cli_sockaddr.sun_path,new_cli_fd); for (ci=1;ci<=2;ci++){ if(watch_fd_list[ci] != -1) continue; else{ watch_fd_list[ci] = new_cli_fd; break; } } FD_SET(new_cli_fd , &watchset ) ; if ( maxfd < new_cli_fd ) { maxfd = new_cli_fd ; } for ( ci=0;ci<=1;ci++){ if(cli_info_t[ci].cli_sock_fd == -1) { cli_info_t[ci].module_id=cli_sockaddr.sun_path[0]; cli_info_t[ci].cli_sock_fd=new_cli_fd; break; } } continue; } |
在上面的程序中,Server运用系统调用函数FD_ISSET来检查是否有客户端的连接请求到达Listening Socket, 如果返回值大于0,Server生成一个新的通信Socket (new_cli_fd)与客户端连接。将新生成的通信Socket放入Socket监视集合中(FD_SET)。将客户端的信息(ID号和Socket描述号)保存在注册表cli_info_t中
for ( ci = 1; ci<=2 ; ci++ ) { int dst_fd = -1 ; char dst_module_id; char src_module_id; int i; if (watch_fd_list[ ci ]==-1) continue; if ( !FD_ISSET( watch_fd_list[ ci ], &catch_fd_set ) ) { continue ; } ioctl(watch_fd_list[ ci ],FIONREAD,&nread); if (nread==0){ continue; } read( watch_fd_list[ ci ], &dst_module_id, 1 ) ; for (i=0;i<=1;i++){ if(cli_info_t[i].module_id == dst_module_id) dst_fd= cli_info_t[i].cli_sock_fd; if(cli_info_t[i].cli_sock_fd==watch_fd_list[ ci ]) src_module_id= cli_info_t[i].module_id; } read( watch_fd_list[ ci ], &ch, 1 ) ; printf("SERVER::char=%c to Client %c on socket%d\n",ch, dst_module_id,dst_fd); write(dst_fd,&src_module_id, 1 ) ; write(dst_fd,&ch, 1 ) ; } } } |
在上面的程序中,如果有数据到达某个通信Socket,Server则读出数据并取出收信客户端ID号。在ID登记表中找到收信客户端对应的Socket描述号。并将数据通过对应Socket传送到收信客户端
ClientB的程序只需将 char dst_module_id='B'; 改为char dst_module_id='A'; char ch='1'; 改为char char ch='2';既可。
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <sys/un.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> int main(){ int client_sockfd; int len; struct sockaddr_un server_sockaddr,cli_sockaddr; int result; char dst_module_id='B'; char ch='1'; char src_module_id; client_sockfd= socket(AF_UNIX,SOCK_STREAM,0); cli_sockaddr.sun_family = AF_UNIX ; strcpy( cli_sockaddr.sun_path, "A" ) ; bind(client_sockfd,(struct sockaddr * )&cli_sockaddr, sizeof( cli_sockaddr ) ) ; server_sockaddr.sun_family=AF_UNIX; strcpy( server_sockaddr.sun_path, "server_socket" ) ; len=sizeof(server_sockaddr); result = connect(client_sockfd,( struct sockaddr * )&server_sockaddr,len); if (result <0){ printf("ClientA::error on connecting \n"); exit(1); } printf("ClientA::succeed in connecting with server\n"); sleep(10); write(client_sockfd,&dst_module_id,1); write(client_sockfd,&ch,1); read (client_sockfd,&src_module_id,1); read (client_sockfd,&ch,1); printf("ClientA::char from Client %c =%c\n", src_module_id,ch); close (client_sockfd); } |
下面是样本程序的执行结果
[root@zhou test]# ./server & [3] 4301 [root@zhou test]# SERVER::Server is waitting on socket=3 ./clientA & ./clientB & [4] 4302 [5] 4303 ClientA::succeed in connecting with server SERVER::open communication with Client A on socket 4 [root@zhou test]# SERVER::open communication with Client B on socket 5 ClientB::succeed in connecting with server SERVER::char=1 to Client B on socket5 ClientB::char from Client A =1 SERVER::char=2 to Client A on socket4 ClientA::char from Client B =2 |
http://blog.csdn.net/xnwyd/article/details/7359506
linux socket进程通信
socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。
一。创建socket服务端的流程如下:
(1)创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信:
- int server_fd;
- int client_fd;//client file descriptor
- struct sockaddr_un server_addr;
- struct sockaddr_un client_addr;
- size_t server_len,client_len;
- //cteate server socket
- //delete old socket file
- unlink(SERVER_NAME);
- if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
- perror("socket");
- exit(1);
- }
(2)命名socket。这里面有一个很关键的东西,socket进程通信命名方式有两种。一是普通的命名,socket会根据此命名创建一个同名的socket文件,客户端连接的时候通过读取该socket文件连接到socket服务端。这种方式的弊端是服务端必须对socket文件的路径具备写权限,客户端必须知道socket文件路径,且必须对该路径有读权限。另外一种命名方式是抽象命名空间,这种方式不需要创建socket文件,只需要命名一个全局名字,即可让客户端根据此名字进行连接。后者的实现过程与前者的差别是,后者在对地址结构成员sun_path数组赋值的时候,必须把第一个字节置0,即sun_path[0] = 0,下面用代码说明:
第一种方式:
- //name the server socket
- server_addr.sun_family = AF_UNIX;
- strcpy(server_addr.sun_path,SERVER_NAME);
- server_len = sizeof(struct sockaddr_un);
- client_len = server_len;
- //name the socket
- server_addr.sun_family = AF_UNIX;
- strcpy(server_addr.sun_path, SERVER_NAME);
- server_addr.sun_path[0]=0;
- //server_len = sizeof(server_addr);
- server_len = strlen(SERVER_NAME) + offsetof(struct sockaddr_un, sun_path);
- #define SERVER_NAME @socket_server
或者可以把第二种方式的实现封装成一个函数:
- int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)
- {
- int nameLen = strlen(name);
- if (nameLen >= (int) sizeof(pAddr->sun_path) -1) /* too long? */
- return -1;
- pAddr->sun_path[0] = '\0'; /* abstract namespace */
- strcpy(pAddr->sun_path+1, name);
- pAddr->sun_family = AF_UNIX;
- *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);
- return 0;
- }
像下面这样使用这个函数:
- makeAddr("server_socket", &server_addr, &server_len);
提示:客户端连接服务器的时候,必须与服务端的命名方式相同,即如果服务端是普通命名方式,客户端的地址也必须是普通命名方式;如果服务端是抽象命名方式,客户端的地址也必须是抽象命名方式。
(3)绑定并侦听
- bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);
- //listen the server
- listen(server_sockfd, 5);
(4)等待客户端连接,并读写数据。
- while(1){
- printf("server waiting...\n");
- //accept client connect
- client_len = sizeof(client_addr);
- client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr, &client_len);
- //read data from client socket
- read(client_sockfd, &ch, 1);
- printf("read from client %d: %c",client_sockfd,ch);
- ch ++;
- write(client_sockfd, &ch, 1);
- close(client_sockfd);
- usleep(100);//1000 miliseconds = 1 second
- }
二 socket客户端创建流程
(1)创建socket
(2)命名socket
(3)连接到服务端:
- //connect to server
- result = connect(sockfd, (struct sockaddr*)&address, len);
(4)与服务端进行通信
- //communicate with server socket
- while(1)
- {
- printf("set send content:");
- scanf("%c",&ch);
- write(sockfd, &ch, 1);
- printf("send to server:%c \n",ch);
- read(sockfd, &ch, 1);
- printf("read from server: %c\n", ch);
- }
完整代码如下:
(1)服务端server.c:
- #include<sys/types.h>
- #include<sys/socket.h>
- #include<stdio.h>
- #include<sys/un.h>
- #include<unistd.h>
- #include<stdlib.h>
- #include <stddef.h>
- #define SERVER_NAME "@server_socket"
- /*
- * Create a UNIX-domain socket address in the Linux "abstract namespace".
- *
- * The socket code doesn't require null termination on the filename, but
- * we do it anyway so string functions work.
- */
- int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)
- {
- int nameLen = strlen(name);
- if (nameLen >= (int) sizeof(pAddr->sun_path) -1) /* too long? */
- return -1;
- pAddr->sun_path[0] = '\0'; /* abstract namespace */
- strcpy(pAddr->sun_path+1, name);
- pAddr->sun_family = AF_UNIX;
- *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);
- return 0;
- }
- int main()
- {
- int server_sockfd, client_sockfd;
- socklen_t server_len, client_len;
- struct sockaddr_un server_addr;
- struct sockaddr_un client_addr;
- char ch;
- int nread;
- //delete the old server socket
- //unlink("server_socket");
- //create socket
- server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
- //name the socket
- server_addr.sun_family = AF_UNIX;
- strcpy(server_addr.sun_path, SERVER_NAME);
- server_addr.sun_path[0]=0;
- //server_len = sizeof(server_addr);
- server_len = strlen(SERVER_NAME) + offsetof(struct sockaddr_un, sun_path);
- //makeAddr("server_socket", &server_addr, &server_len);
- bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);
- //listen the server
- listen(server_sockfd, 5);
- client_sockfd = -1;
- client_len = sizeof(client_addr);
- while(1){
- printf("server waiting...\n");
- //accept client connect
- if(client_sockfd == -1){
- client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr, &client_len);
- }
- //read data from client socket
- nread = read(client_sockfd, &ch, 1);
- if(nread == 0){//client disconnected
- printf("client %d disconnected\n",client_sockfd);
- client_sockfd = -1;
- }
- else{
- printf("read from client %d: %c\n",client_sockfd,ch);
- ch ++;
- write(client_sockfd, &ch, 1);
- }
- usleep(100);//1000 miliseconds = 1 second
- }
- return 0;
- }
(2)客户端client.c
- #include<sys/types.h>
- #include<sys/socket.h>
- #include<stdio.h>
- #include<sys/un.h>
- #include<unistd.h>
- #include<stdlib.h>
- #include <stddef.h>
- #define SERVER_NAME "@server_socket"
- /*
- * Create a UNIX-domain socket address in the Linux "abstract namespace".
- *
- * The socket code doesn't require null termination on the filename, but
- * we do it anyway so string functions work.
- */
- int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)
- {
- int nameLen = strlen(name);
- if (nameLen >= (int) sizeof(pAddr->sun_path) -1) /* too long? */
- return -1;
- pAddr->sun_path[0] = '\0'; /* abstract namespace */
- strcpy(pAddr->sun_path+1, name);
- pAddr->sun_family = AF_UNIX;
- *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);
- return 0;
- }
- int main()
- {
- int sockfd;
- socklen_t len;
- struct sockaddr_un address;
- int result;
- char ch = 'A';
- //create socket
- sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
- //name the server socket
- //makeAddr("server_socket", &address, &len);
- address.sun_family = AF_UNIX;
- strcpy(address.sun_path, SERVER_NAME);
- address.sun_path[0]=0;
- //len = sizeof(address);
- len = strlen(SERVER_NAME) + offsetof(struct sockaddr_un, sun_path);
- //connect to server
- result = connect(sockfd, (struct sockaddr*)&address, len);
- if(result == -1)
- {
- perror("opps:client1");
- exit(1);
- }
- //communicate with server socket
- while(1)
- {
- printf("set send content:");
- scanf("%c",&ch);
- write(sockfd, &ch, 1);
- printf("send to server:%c \n",ch);
- read(sockfd, &ch, 1);
- printf("read from server: %c\n", ch);
- }
- exit(0);
- }
http://www.cnblogs.com/ladd/archive/2012/06/25/2560888.html
Linux 下socket通信终极指南(附TCP、UDP完整代码)
linux下用socket通信,有TCP、UDP两种协议,网上的很多教程把两个混在了一起,或者只讲其中一种。现在我把自己这两天研究的成果汇总下来,写了一个完整的,适合初学者参考,也方便自己以后查阅。
首先讲什么是socket,不喜欢理论的可以略过。
Berkeley套接字应用程序接口(API)包括了一个用C语言写成的应用程序开发库,主要用于实现进程间通讯,在计算机网络通讯方面被广泛使用。(来自 wikipedia socket )
下面介绍一下常用的socket API(也来自 wikipedia socket)
这个列表是一个Berkeley套接字API库提供的函数或者方法的概要:
socket()
创建一个新的确定类型的套接字,类型用一个整型数值标识,并为它分配系统资源。bind()
一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。listen()
用于服务器端,使一个绑定的TCP套接字进入监听状态。connect()
用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。accept()
用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。send()
和recv()
,或者write()
和read()
,或者recvfrom()
和sendto()
, 用于往/从远程套接字发送和接受数据。close()
用于系统释放分配给一个套接字的资源。 如果是TCP,连接会被中断。gethostbyname()
和gethostbyaddr()
用于解析主机名和地址。select()
用于修整有如下情况的套接字列表: 准备读,准备写或者是有错误。poll()
用于检查套接字的状态。 套接字可以被测试,看是否可以写入、读取或是有错误。getsockopt()
用于查询指定的套接字一个特定的套接字选项的当前值。setsockopt()
用于为指定的套接字设定一个特定的套接字选项。
更多的细节如下给出。
[编辑]socket()
socket()
为通讯创建一个端点,为套接字返回一个文件描述符。 socket() 有三个参数:
- domain 为创建的套接字指定协议集。 例如:
PF_INET
表示IPv4网络协议PF_INET6
表示IPv6PF_UNIX
表示本地套接字(使用一个文件)
- type 如下:
SOCK_STREAM
(可靠的面向流服务或流套接字)SOCK_DGRAM
(数据报文服务或者数据报文套接字)SOCK_SEQPACKET
(可靠的连续数据包服务)SOCK_RAW
(在网络层之上的原始协议)。
- protocol 指定实际使用的传输协议。 最常见的就是
IPPROTO_TCP
、IPPROTO_SCTP
、IPPROTO_UDP
、IPPROTO_DCCP
。这些协议都在<netinet/in.h>中有详细说明。 如果该项为“0
”的话,即根据选定的domain和type选择使用缺省协议。
如果发生错误,函数返回值为-1。 否则,函数会返回一个代表新分配的描述符的整数。
-
原型:
<span class="kw4" style="margin: 0px; padding: 0px;">int</span> socket<span class="br0" style="margin: 0px; padding: 0px;">(</span><span class="kw4" style="margin: 0px; padding: 0px;">int</span> domain<span class="sy0" style="margin: 0px; padding: 0px;">,</span> <span class="kw4" style="margin: 0px; padding: 0px;">int</span> type<span class="sy0" style="margin: 0px; padding: 0px;">,</span> <span class="kw4" style="margin: 0px; padding: 0px;">int</span> protocol<span class="br0" style="margin: 0px; padding: 0px;">)</span>。
[编辑]bind()
bind()
为一个套接字分配地址。当使用socket()
创建套接字后,只赋予其所使用的协议,并未分配地址。在接受其它主机的连接前,必须先调用bind()为套接字分配一个地址。bind()
有三个参数:
sockfd
, 表示使用bind函数的套接字描述符my_addr
, 指向sockaddr结构(用于表示所分配地址)的指针addrlen
, 用socklen_t字段指定了sockaddr结构的长度
如果发生错误,函数返回值为-1,否则为0。
-
原型
<span class="kw4" style="margin: 0px; padding: 0px;">int</span> bind<span class="br0" style="margin: 0px; padding: 0px;">(</span><span class="kw4" style="margin: 0px; padding: 0px;">int</span> sockfd<span class="sy0" style="margin: 0px; padding: 0px;">,</span> <span class="kw4" style="margin: 0px; padding: 0px;">const</span> <span class="kw4" style="margin: 0px; padding: 0px;">struct</span> sockaddr <span class="sy0" style="margin: 0px; padding: 0px;">*</span>my_addr<span class="sy0" style="margin: 0px; padding: 0px;">,</span> socklen_t addrlen<span class="br0" style="margin: 0px; padding: 0px;">)</span><span class="sy0" style="margin: 0px; padding: 0px;">;</span>
[编辑]listen()
当socket和一个地址绑定之后,listen()
函数会开始监听可能的连接请求。然而,这只能在有可靠数据流保证的时候使用,例如:数据类型(SOCK_STREAM
,SOCK_SEQPACKET
)。
listen()函数需要两个参数:
sockfd
, 一个socket的描述符.backlog
, 一个决定监听队列大小的整数,当有一个连接请求到来,就会进入此监听队列,当队列满后,新的连接请求会返回错误。当请求被接受,返回 0。反之,错误返回 -1。
原型:
<span class="kw4" style="margin: 0px; padding: 0px;">int</span> listen<span class="br0" style="margin: 0px; padding: 0px;">(</span><span class="kw4" style="margin: 0px; padding: 0px;">int</span> sockfd<span class="sy0" style="margin: 0px; padding: 0px;">,</span> <span class="kw4" style="margin: 0px; padding: 0px;">int</span> backlog<span class="br0" style="margin: 0px; padding: 0px;">)</span><span class="sy0" style="margin: 0px; padding: 0px;">;</span>
[编辑]accept()
当应用程序监听来自其他主机的面对数据流的连接时,通过事件(比如Unix select()系统调用)通知它。必须用 accept()
函数初始化连接。 Accept() 为每个连接创立新的套接字并从监听队列中移除这个连接。它使用如下参数:
sockfd
,监听的套接字描述符cliaddr
, 指向sockaddr 结构体的指针,客户机地址信息。addrlen
,指向socklen_t
的指针,确定客户机地址结构体的大小 。
返回新的套接字描述符,出错返回-1。进一步的通信必须通过这个套接字。
Datagram 套接字不要求用accept()处理,因为接收方可能用监听套接字立即处理这个请求。
-
函数原型:
<span class="kw4" style="margin: 0px; padding: 0px;">int</span> accept<span class="br0" style="margin: 0px; padding: 0px;">(</span><span class="kw4" style="margin: 0px; padding: 0px;">int</span> sockfd<span class="sy0" style="margin: 0px; padding: 0px;">,</span> <span class="kw4" style="margin: 0px; padding: 0px;">struct</span> sockaddr <span class="sy0" style="margin: 0px; padding: 0px;">*</span>cliaddr<span class="sy0" style="margin: 0px; padding: 0px;">,</span> socklen_t <span class="sy0" style="margin: 0px; padding: 0px;">*</span>addrlen<span class="br0" style="margin: 0px; padding: 0px;">)</span><span class="sy0" style="margin: 0px; padding: 0px;">;</span>
[编辑]connect()
connect()
系统调用为一个套接字设置连接,参数有文件描述符和主机地址。
某些类型的套接字是无连接的,大多数是UDP协议。对于这些套接字,连接时这样的:默认发送和接收数据的主机由给定的地址确定,可以使用 send()和 recv()。 返回-1表示出错,0表示成功。
-
函数原型:
<span class="kw4" style="margin: 0px; padding: 0px;">int</span> connect<span class="br0" style="margin: 0px; padding: 0px;">(</span><span class="kw4" style="margin: 0px; padding: 0px;">int</span> sockfd<span class="sy0" style="margin: 0px; padding: 0px;">,</span> <span class="kw4" style="margin: 0px; padding: 0px;">const</span> <span class="kw4" style="margin: 0px; padding: 0px;">struct</span> sockaddr <span class="sy0" style="margin: 0px; padding: 0px;">*</span>serv_addr<span class="sy0" style="margin: 0px; padding: 0px;">,</span> socklen_t addrlen<span class="br0" style="margin: 0px; padding: 0px;">)</span><span class="sy0" style="margin: 0px; padding: 0px;">;</span>
TCP socket通信
服务器端流程如下:
1.创建serverSocket
2.初始化 serverAddr(服务器地址)
3.将socket和serverAddr 绑定 bind
4.开始监听 listen
5.进入while循环,不断的accept接入的客户端socket,进行读写操作write和read
6.关闭serverSocket
客户端流程:
1.创建clientSocket
2.初始化 serverAddr
3.链接到服务器 connect
4.利用write和read 进行读写操作
5.关闭clientSocket
具体实现代码如下
- #server.c(TCP)
- <pre name="code" class="cpp">#include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <errno.h>
- #define SRVPORT 10005
- #define CONNECT_NUM 5
- #define MAX_NUM 80
- int main()
- {
- int serverSock=-1,clientSock=-1;
- struct sockaddr_in serverAddr;
- serverSock=socket(AF_INET,SOCK_STREAM,0);
- if(serverSock<0)
- {
- printf("socket creation failed\n");
- exit(-1);
- }
- printf("socket create successfully.\n");
- memset(&serverAddr,0,sizeof(serverAddr));
- serverAddr.sin_family=AF_INET;
- serverAddr.sin_port=htons((u_short) SRVPORT);
- serverAddr.sin_addr.s_addr=htons(INADDR_ANY);
- if(bind(serverSock,&serverAddr,sizeof(struct sockaddr_in))==-1)
- {
- printf("Bind error.\n");
- exit(-1);
- }
- printf("Bind successful.\n");
- if(listen(serverSock,10)==-1)
- {
- printf("Listen error!\n");
- }
- printf("Start to listen!\n");
- char revBuf[MAX_NUM]={0};
- char sedBuf[MAX_NUM]={0};
- while(1)
- {
- clientSock=accept(serverSock,NULL,NULL);
- while(1)
- {
- if(read(clientSock,revBuf,MAX_NUM)==-1)
- {
- printf("read error.\n");
- }
- else
- {
- printf("Client:%s\n",revBuf);
- }
- if(strcmp(revBuf,"Quit")==0||strcmp(revBuf,"quit")==0)
- {
- strcpy(sedBuf,"Goodbye,my dear client!");
- }
- else
- {
- strcpy(sedBuf,"Hello Client.");
- }
- if(write(clientSock,sedBuf,sizeof(sedBuf))==-1)
- {
- printf("Send error!\n");
- }
- printf("Me(Server):%s\n",sedBuf);
- if(strcmp(revBuf,"Quit")==0||strcmp(revBuf,"quit")==0)
- {
- break;
- }
- bzero(revBuf,sizeof(revBuf));
- bzero(sedBuf,sizeof(sedBuf));
- }
- close(clientSock);
- }
- close(serverSock);
- return 0;
- }</pre><br>
- <pre></pre>
- <pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);"></pre><pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);"></pre><pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);"></pre><pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);">#client.c(TCP)
- </pre><pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);"><pre name="code" class="cpp">#include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <errno.h>
- #include <string.h>
- #define SRVPORT 10005
- #define CONNECT_NUM 5
- #define MAX_NUM 80
- int main()
- {
- int clientSock=-1;
- struct sockaddr_in serverAddr;
- clientSock=socket(AF_INET,SOCK_STREAM,0);
- if(clientSock<0)
- {
- printf("socket creation failed\n");
- exit(-1);
- }
- printf("socket create successfully.\n");
- memset(&serverAddr,0,sizeof(serverAddr));
- serverAddr.sin_family=AF_INET;
- serverAddr.sin_port=htons((u_short) SRVPORT);
- serverAddr.sin_addr.s_addr=htons(INADDR_ANY);
- if(connect(clientSock,&serverAddr,sizeof(struct sockaddr_in))<0)
- {
- printf("Connect error.\n");
- exit(-1);
- }
- printf("Connect successful.\n");
- char sedBuf[MAX_NUM]={0};
- char revBuf[MAX_NUM]={0};
- while(gets(sedBuf)!=-1)
- {
- if(write(clientSock,sedBuf,strlen(sedBuf))==-1)
- {
- printf("send error!\n");
- }
- printf("Me(Client):%s\n",sedBuf);
- bzero(sedBuf,sizeof(sedBuf));
- if(read(clientSock,revBuf,MAX_NUM)==-1)
- {
- printf("rev error!\n");
- }
- printf("Sever:%s\n",revBuf);
- if(strcmp(revBuf,"Goodbye,my dear client!")==0)
- break;
- bzero(revBuf,sizeof(revBuf));
- }
- close(clientSock);
- return 0;
- }
- </pre><br>
- <br>
- <pre></pre>
- <pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);"></pre><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)"><span style="margin:0px; padding:0px">UDP协议不能保证数据通信的可靠性,但是开销更低,编起来也更加简单</span></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">服务器流程:</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">1.创建serverSocket</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">2.设置服务器地址 serverAddr</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">3.将serverSocket和serverAddr绑定 bind</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">4.开始进行读写 sendto和recvfrom</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">5.关闭serverSocket</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">客户端流程</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">1.创建clientSocket</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">2.设置服务器地址 serverAddr</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">3.可选 设置clientAddr并和clientSocket(一般不用绑定)</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">4.进行发送操作 sendto</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">5.关闭clientSocket</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">具体代码如下:</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)"> </p><pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);">#server.c(UDP)
- <pre name="code" class="cpp">#include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <netinet/in.h>//for sockaddr_in
- #include <arpa/inet.h>//for socket
- int main()
- {
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- if(fd == -1)
- {
- perror("socket create error!\n");
- exit(-1);
- }
- printf("socket fd=%d\n", fd);
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(6666);
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- int r;
- r = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
- if(r == -1)
- {
- printf("Bind error!\n");
- close(fd);
- exit(-1);
- }
- printf("Bind successfully.\n");
- char buf[255];
- struct sockaddr_in from;
- socklen_t len;
- len = sizeof(from);
- while(1)
- {
- r = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&from, &len);
- if(r > 0)
- {
- buf[r] = 0;
- printf("The message received for %s is :%s\n", inet_ntoa(from.sin_addr), buf);
- }
- else
- {
- break;
- }
- }
- close(fd);
- return 0;
- }</pre><br>
- <br>
- <pre></pre>
- <p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">
- </p>
- <pre name="code" class="cpp" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 19px; background-color: rgb(245, 245, 245);">#client.c(UDP)
- <pre name="code" class="cpp">#include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <netinet/in.h>//for sockaddr_in
- #include <arpa/inet.h>//for socket
- int main()
- {
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- if(fd == -1)
- {
- perror("socket create error!\n");
- exit(-1);
- }
- printf("socket fd=%d\n", fd);
- struct sockaddr_in addr_to;//目标服务器地址
- addr_to.sin_family = AF_INET;
- addr_to.sin_port = htons(6666);
- addr_to.sin_addr.s_addr = inet_addr("127.0.0.1");
- struct sockaddr_in addr_from;
- addr_from.sin_family = AF_INET;
- addr_from.sin_port = htons(0); //获得任意空闲端口
- addr_from.sin_addr.s_addr = htons(INADDR_ANY); //获得本机地址
- r = bind(fd, (struct sockaddr *)&addr_from, sizeof(addr_from));
- int r;
- if(r == -1)
- {
- printf("Bind error!\n");
- close(fd);
- exit(-1);
- }
- printf("Bind successfully.\n");
- char buf[255];
- int len;
- while(1)
- {
- r = read(0, buf, sizeof(buf));
- if(r < 0)
- {
- break;
- }
- len = sendto(fd, buf, r, 0, (struct sockaddr *)&addr_to, sizeof(addr_to));
- if(len == -1)
- {
- printf("send falure!\n");
- }
- else
- {
- printf("%d bytes have been sended successfully!\n", len);
- }
- }
- close(fd);
- return 0;
- }</pre><br>
- <br>
- <pre></pre>
- <p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">
- <br style="margin:0px; padding:0px">
- <span style="margin:0px; padding:0px">以上代码均经过测试(Ubuntu12.04),可以运行。有疑问,可以发电邮到ladd.cn@gmail.com</span></p>
- <p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">
- </p>
- <p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">
- 参考文章</p>
- <p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">
- 1.wikipedia socket <a href="http://zh.wikipedia.org/wiki/Socket" style="margin:0px; padding:0px; color:rgb(0,105,214); line-height:inherit">http://zh.wikipedia.org/wiki/Socket</a></p>
- <p style="margin:10px auto; padding-top:0px; padding-bottom:0px; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; font-size:13px; line-height:19px; background-color:rgb(245,245,245)">
- 2.TCP socket 之linux实现<a href="http://os.51cto.com/art/201001/179878.htm" style="margin:0px; padding:0px; color:rgb(0,105,214); line-height:inherit">http://os.51cto.com/art/201001/179878.htm</a></p>
- <div style="top:8719px">
- <p><span style="color:rgb(51,51,51); font-family:Helvetica,Tahoma,Arial,sans-serif; font-size:14px; line-height:24px"></span></p>
- <p><span style="color:rgb(51,51,51); font-family:Helvetica,Tahoma,Arial,sans-serif; font-size:14px; line-height:24px"></span></p>
- </div>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- </pre></pre></pre>