Last active
August 15, 2018 09:40
-
-
Save zxlooong/5262922 to your computer and use it in GitHub Desktop.
socket
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <aio.h> | |
#include <pthread.h> | |
#define BUF_SIZE 1024 | |
void aio_completion_handler(sigval_t sigval); | |
void setup_io(int fd, aiocb& my_aiocb) | |
{ | |
//初始化AIO请求 | |
bzero( (char *)&my_aiocb, sizeof(struct aiocb) ); | |
my_aiocb.aio_fildes = fd; | |
my_aiocb.aio_buf = malloc(BUF_SIZE+1); | |
my_aiocb.aio_nbytes = BUF_SIZE; | |
my_aiocb.aio_offset = 0; | |
//设置线程回调函数 | |
my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD; | |
my_aiocb.aio_sigevent.sigev_notify_function = aio_completion_handler; | |
my_aiocb.aio_sigevent.sigev_notify_attributes = NULL; | |
my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb; | |
} | |
//回调函数 | |
void aio_completion_handler(sigval_t sigval) | |
{ | |
struct aiocb *req; | |
int ret; | |
req = (struct aiocb *)sigval.sival_ptr; | |
if (aio_error(req) == 0) | |
{ | |
if((ret = aio_return(req)) > 0) | |
{ | |
printf("Thread id %u recv:%s\n", (unsigned int)pthread_self(), (char*)req->aio_buf); | |
} | |
} | |
char* buf = (char*)req->aio_buf; | |
if(send(req->aio_fildes, buf, strlen(buf), 0) == -1) | |
{ | |
perror("send"); | |
return; | |
} | |
close(req->aio_fildes); | |
return; | |
} | |
int main() | |
{ | |
int sockfd; | |
int sin_size; | |
struct sockaddr_in addr, cliaddr; | |
//创建socket | |
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
{ | |
perror("createSocket"); | |
return -1; | |
} | |
//初始化socket结构 | |
memset(&addr, 0, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_port = htons(7092); | |
addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
//绑定套接口 | |
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr))==-1) | |
{ | |
perror("bind"); | |
return -1; | |
} | |
//创建监听套接口 | |
if(listen(sockfd,10)==-1) | |
{ | |
perror("listen"); | |
return -1; | |
} | |
printf("server is running!\n"); | |
//等待连接 | |
while(1) | |
{ | |
int new_fd; | |
struct aiocb my_aiocb; | |
sin_size = sizeof(struct sockaddr_in); | |
//接受连接 | |
if((new_fd = accept(sockfd, (struct sockaddr *)&cliaddr, (socklen_t*)&sin_size))==-1) | |
{ | |
perror("accept"); | |
return -1; | |
} | |
printf("Thread id %u accept connect, fd: %d\n", (unsigned int)pthread_self(), new_fd); | |
setup_io(new_fd, my_aiocb); | |
aio_read(&my_aiocb); | |
} | |
close(sockfd); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
int main() | |
{ | |
int sockfd, new_fd; | |
int sin_size, numbytes; | |
struct sockaddr_in addr, cliaddr; | |
//创建socket | |
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
{ | |
perror("createSocket"); | |
return -1; | |
} | |
//初始化socket结构 | |
memset(&addr, 0, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_port = htons(7092); | |
addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
//绑定套接口 | |
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr))==-1) | |
{ | |
perror("bind"); | |
return -1; | |
} | |
//创建监听套接口 | |
if(listen(sockfd,10)==-1) | |
{ | |
perror("listen"); | |
return -1; | |
} | |
printf("server is running!\n"); | |
char buff[1024]; | |
//等待连接 | |
while(1) | |
{ | |
sin_size = sizeof(struct sockaddr_in); | |
//接受连接 | |
if((new_fd = accept(sockfd, (struct sockaddr *)&cliaddr, (socklen_t*)&sin_size))==-1) | |
{ | |
perror("accept"); | |
return -1; | |
} | |
//生成一个子进程来完成和客户端的会话,父进程继续监听 | |
if(!fork()) | |
{ | |
//读取客户端发来的信息 | |
memset(buff,0,sizeof(buff)); | |
if((numbytes = recv(new_fd,buff,sizeof(buff),0))==-1) | |
{ | |
perror("recv"); | |
return -1; | |
} | |
printf("buff=%s\n",buff); | |
//将从客户端接收到的信息再发回客户端 | |
if(send(new_fd,buff,strlen(buff),0)==-1) | |
{ | |
perror("send"); | |
} | |
close(new_fd); | |
return 0; | |
} | |
//父进程关闭new_fd | |
close(new_fd); | |
} | |
close(sockfd); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <sys/epoll.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <errno.h> | |
#include <iostream> | |
using namespace std; | |
#define MAX_EVENTS 1024 | |
struct myevent_s | |
{ | |
int fd; | |
void (*call_back)(int fd, int events, void *arg); | |
int events; | |
void *arg; | |
int status; // 1: in epoll wait list, 0 not in | |
char buff[128]; // recv data buffer | |
int len; | |
long last_active; // last active time | |
}; | |
int g_epollFd; | |
myevent_s g_Events[MAX_EVENTS+1]; // g_Events[MAX_EVENTS] is used by listen fd | |
void RecvData(int fd, int events, void *arg); | |
void SendData(int fd, int events, void *arg); | |
// set event | |
void EventSet(myevent_s *ev, int fd, void (*call_back)(int, int, void*), void *arg) | |
{ | |
ev->fd = fd; | |
ev->call_back = call_back; | |
ev->events = 0; | |
ev->arg = arg; | |
ev->status = 0; | |
ev->len = 0; | |
ev->last_active = time(NULL); | |
} | |
// add/mod an event to epoll | |
void EventAdd(int epollFd, int events, myevent_s *ev) | |
{ | |
struct epoll_event epv = {0, {0}}; | |
int op; | |
epv.data.ptr = ev; | |
epv.events = ev->events = events; | |
if(ev->status == 1){ | |
op = EPOLL_CTL_MOD; | |
} | |
else{ | |
op = EPOLL_CTL_ADD; | |
ev->status = 1; | |
} | |
if(epoll_ctl(epollFd, op, ev->fd, &epv) < 0) | |
printf("Event Add failed[fd=%d]\n", ev->fd); | |
else | |
printf("Event Add OK[fd=%d]\n", ev->fd); | |
} | |
// delete an event from epoll | |
void EventDel(int epollFd, myevent_s *ev) | |
{ | |
struct epoll_event epv = {0, {0}}; | |
if(ev->status != 1) return; | |
epv.data.ptr = ev; | |
ev->status = 0; | |
epoll_ctl(epollFd, EPOLL_CTL_DEL, ev->fd, &epv); | |
} | |
// accept new connections from clients | |
void AcceptConn(int fd, int events, void *arg) | |
{ | |
struct sockaddr_in sin; | |
socklen_t len = sizeof(struct sockaddr_in); | |
int nfd, i; | |
// accept | |
if((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -1) | |
{ | |
if(errno != EAGAIN && errno != EINTR) | |
{ | |
printf("%s: bad accept", __func__); | |
} | |
return; | |
} | |
do | |
{ | |
for(i = 0; i < MAX_EVENTS; i++) | |
{ | |
if(g_Events[i].status == 0) | |
{ | |
break; | |
} | |
} | |
if(i == MAX_EVENTS) | |
{ | |
printf("%s:max connection limit[%d].", __func__, MAX_EVENTS); | |
break; | |
} | |
// set nonblocking | |
if(fcntl(nfd, F_SETFL, O_NONBLOCK) < 0) break; | |
// add a read event for receive data | |
EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]); | |
EventAdd(g_epollFd, EPOLLIN|EPOLLET, &g_Events[i]); | |
printf("new conn[%s:%d][time:%d]\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), g_Events[i].last_active); | |
}while(0); | |
} | |
// receive data | |
void RecvData(int fd, int events, void *arg) | |
{ | |
struct myevent_s *ev = (struct myevent_s*)arg; | |
int len; | |
// receive data | |
len = recv(fd, ev->buff, sizeof(ev->buff)-1, 0); | |
EventDel(g_epollFd, ev); | |
if(len > 0) | |
{ | |
ev->len = len; | |
ev->buff[len] = '\0'; | |
printf("C[%d]:%s\n", fd, ev->buff); | |
// change to send event | |
EventSet(ev, fd, SendData, ev); | |
EventAdd(g_epollFd, EPOLLOUT|EPOLLET, ev); | |
} | |
else if(len == 0) | |
{ | |
close(ev->fd); | |
printf("[fd=%d] closed gracefully.\n", fd); | |
} | |
else | |
{ | |
close(ev->fd); | |
printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno)); | |
} | |
} | |
// send data | |
void SendData(int fd, int events, void *arg) | |
{ | |
struct myevent_s *ev = (struct myevent_s*)arg; | |
int len; | |
time_t now = time(0); | |
sprintf(ev->buff, "Server Time is : %s", ctime(&now)); | |
// send data | |
len = send(fd, ev->buff, strlen(ev->buff), 0); | |
ev->len = 0; | |
EventDel(g_epollFd, ev); | |
if(len > 0) | |
{ | |
// change to receive event | |
EventSet(ev, fd, RecvData, ev); | |
EventAdd(g_epollFd, EPOLLIN|EPOLLET, ev); | |
} | |
else | |
{ | |
close(ev->fd); | |
printf("recv[fd=%d] error[%d]\n", fd, errno); | |
} | |
} | |
void InitListenSocket(int epollFd, short port) | |
{ | |
int listenFd = socket(AF_INET, SOCK_STREAM, 0); | |
fcntl(listenFd, F_SETFL, O_NONBLOCK); // set non-blocking | |
printf("server listen fd=%d\n", listenFd); | |
EventSet(&g_Events[MAX_EVENTS], listenFd, AcceptConn, &g_Events[MAX_EVENTS]); | |
// add listen socket | |
EventAdd(epollFd, EPOLLIN|EPOLLET, &g_Events[MAX_EVENTS]); | |
// bind & listen | |
sockaddr_in sin; | |
bzero(&sin, sizeof(sin)); | |
sin.sin_family = AF_INET; | |
sin.sin_addr.s_addr = INADDR_ANY; | |
sin.sin_port = htons(port); | |
bind(listenFd, (const sockaddr*)&sin, sizeof(sin)); | |
listen(listenFd, 5); | |
} | |
int main(int argc, char **argv) | |
{ | |
short port = 7092; // default port | |
// create epoll | |
g_epollFd = epoll_create(MAX_EVENTS); | |
if(g_epollFd <= 0) printf("create epoll failed.%d\n", g_epollFd); | |
// create & bind listen socket, and add to epoll, set non-blocking | |
InitListenSocket(g_epollFd, port); | |
// event loop | |
struct epoll_event events[MAX_EVENTS]; | |
printf("server running:port[%d]\n", port); | |
int checkPos = 0; | |
while(1){ | |
// a simple timeout check here, every time 100, better to use a mini-heap, and add timer event | |
long now = time(NULL); | |
for(int i = 0; i < 100; i++, checkPos++) // doesn't check listen fd | |
{ | |
if(checkPos == MAX_EVENTS) checkPos = 0; // recycle | |
if(g_Events[checkPos].status != 1) continue; | |
long duration = now - g_Events[checkPos].last_active; | |
if(duration >= 60) // 60s timeout | |
{ | |
close(g_Events[checkPos].fd); | |
printf("[fd=%d] timeout[%d--%d].\n", g_Events[checkPos].fd, g_Events[checkPos].last_active, now); | |
EventDel(g_epollFd, &g_Events[checkPos]); | |
} | |
} | |
// wait for events to happen | |
int fds = epoll_wait(g_epollFd, events, MAX_EVENTS, 1000); | |
if(fds < 0){ | |
printf("epoll_wait error, exit\n"); | |
break; | |
} | |
for(int i = 0; i < fds; i++){ | |
myevent_s *ev = (struct myevent_s*)events[i].data.ptr; | |
if((events[i].events&EPOLLIN)&&(ev->events&EPOLLIN)) // read event | |
{ | |
ev->call_back(ev->fd, events[i].events, ev->arg); | |
} | |
if((events[i].events&EPOLLOUT)&&(ev->events&EPOLLOUT)) // write event | |
{ | |
ev->call_back(ev->fd, events[i].events, ev->arg); | |
} | |
} | |
} | |
// free resource | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <netdb.h> | |
#include <sys/epoll.h> | |
#define MAXEVENT 1024 | |
int create_server_socket(int& sockfd) | |
{ | |
struct sockaddr_in addr; | |
//创建socket | |
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
{ | |
perror("createSocket"); | |
return -1; | |
} | |
//初始化socket结构 | |
memset(&addr, 0, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_port = htons(7092); | |
addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
//绑定套接口 | |
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr))==-1) | |
{ | |
perror("bind"); | |
return -1; | |
} | |
//创建监听套接口 | |
if(listen(sockfd,10)==-1) | |
{ | |
perror("listen"); | |
return -1; | |
} | |
return 0; | |
} | |
int set_socket_non_blocking(int fd) | |
{ | |
int flags, s; | |
flags = fcntl (fd, F_GETFL, 0); | |
if (flags == -1) | |
{ | |
perror ("fcntl F_GETFL failed"); | |
return -1; | |
} | |
flags |= O_NONBLOCK; | |
s = fcntl (fd, F_SETFL, flags); | |
if (s == -1) | |
{ | |
perror ("fcntl F_SETFL failed"); | |
return -1; | |
} | |
return 0; | |
} | |
int main() | |
{ | |
int sockfd, efd; | |
struct epoll_event event; | |
struct epoll_event *events; | |
int s; | |
if(create_server_socket(sockfd) != 0) | |
{ | |
perror("create server sock failed\n"); | |
return 1; | |
} | |
set_socket_non_blocking(sockfd); | |
printf("server is running!\n"); | |
//创建一个epoll的句柄 | |
//int epoll_create(int size) | |
//Since Linux 2.6.8, the size argument is unused. (The kernel dynamically sizes the required data structures without needing this initial hint.) | |
efd = epoll_create(MAXEVENT); | |
if (efd == -1) | |
{ | |
perror ("epoll_create"); | |
abort (); | |
} | |
//注册新事件到epoll efd | |
event.data.fd = sockfd; | |
event.events = EPOLLIN | EPOLLET; | |
s = epoll_ctl(efd, EPOLL_CTL_ADD, sockfd, &event); | |
if (s == -1) | |
{ | |
perror ("epoll_ctl EPOLL_CTL_ADD failed"); | |
abort (); | |
} | |
events = (epoll_event*)calloc(MAXEVENT, sizeof(event)); | |
while (1) | |
{ | |
int n, i; | |
n = epoll_wait(efd, events, MAXEVENT, -1); | |
for (i = 0; i < n; i++) | |
{ | |
//fd error | |
if ((events[i].events & EPOLLERR) || | |
(events[i].events & EPOLLHUP) || | |
(!(events[i].events & EPOLLIN))) | |
{ | |
perror("epoll error\n"); | |
close (events[i].data.fd); | |
continue; | |
} | |
//新连接 | |
else if (sockfd == events[i].data.fd) | |
{ | |
while (1) | |
{ | |
struct sockaddr in_addr; | |
socklen_t in_len; | |
int infd; | |
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; | |
//接受连接 | |
in_len = sizeof(in_addr); | |
infd = accept(sockfd, &in_addr, &in_len); | |
if (infd == -1) | |
{ | |
if ((errno == EAGAIN) || | |
(errno == EWOULDBLOCK)) | |
{ | |
//已接受所有连接 | |
break; | |
} | |
else | |
{ | |
perror ("accept"); | |
break; | |
} | |
} | |
s = getnameinfo (&in_addr, in_len, | |
hbuf, sizeof hbuf, | |
sbuf, sizeof sbuf, | |
NI_NUMERICHOST | NI_NUMERICSERV); | |
if (s == 0) | |
{ | |
printf("Accepted connection on descriptor %d " | |
"(host=%s, port=%s)\n", infd, hbuf, sbuf); | |
} | |
/* 设置新接受的socket连接无阻塞*/ | |
s = set_socket_non_blocking (infd); | |
if (s == -1) | |
{ | |
return 1; | |
} | |
//注册新事件到epoll | |
event.data.fd = infd; | |
event.events = EPOLLIN | EPOLLET; | |
s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event); | |
if (s == -1) | |
{ | |
perror ("epoll_ctl"); | |
return 1; | |
} | |
} | |
continue; | |
} | |
//数据可读 | |
else | |
{ | |
int done = 0; | |
while (1) | |
{ | |
ssize_t count; | |
char buf[512]; | |
count = read(events[i].data.fd, buf, sizeof(buf)); | |
if(count == -1) | |
{ | |
//数据读完 | |
if (errno != EAGAIN) | |
{ | |
perror ("read"); | |
done = 1; | |
} | |
break; | |
} | |
else if(count == 0) | |
{ | |
/* End of file. The remote has closed the | |
connection. */ | |
done = 1; | |
break; | |
} | |
printf("recv: %s\n", buf); | |
} | |
if (done) | |
{ | |
printf ("Closed connection on descriptor %d\n", events[i].data.fd); | |
close (events[i].data.fd); | |
} | |
} | |
} | |
} | |
free (events); | |
close(sockfd); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
int main() | |
{ | |
int sockfd, new_fd; | |
int sin_size; | |
struct sockaddr_in addr, cliaddr; | |
//创建socket | |
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
{ | |
perror("createSocket"); | |
return -1; | |
} | |
//初始化socket结构 | |
memset(&addr, 0, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_port = htons(7092); | |
addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
//绑定套接口 | |
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr))==-1) | |
{ | |
perror("bind"); | |
return -1; | |
} | |
//创建监听套接口 | |
if(listen(sockfd,10)==-1) | |
{ | |
perror("listen"); | |
return -1; | |
} | |
printf("server is running!\n"); | |
char buff[1024]; | |
//等待连接 | |
while(1) | |
{ | |
sin_size = sizeof(struct sockaddr_in); | |
//接受连接 | |
if((new_fd = accept(sockfd, (struct sockaddr *)&cliaddr, (socklen_t*)&sin_size))==-1) | |
{ | |
perror("accept"); | |
return -1; | |
} | |
//生成一个子进程来完成和客户端的会话,父进程继续监听 | |
if(!fork()) | |
{ | |
//设置new_fd无阻塞属性 | |
int flags; | |
if((flags=fcntl(new_fd, F_GETFL, 0))<0) | |
{ | |
perror("fcntl F_GETFL"); | |
} | |
flags |= O_NONBLOCK; | |
if(fcntl(new_fd, F_SETFL,flags)<0) | |
{ | |
perror("fcntl F_SETFL"); | |
} | |
//读取客户端发来的信息 | |
memset(buff,0,sizeof(buff)); | |
while(1) | |
{ | |
if((recv(new_fd,buff,sizeof(buff),0)) < 0) | |
{ | |
if(errno==EWOULDBLOCK) | |
{ | |
perror("recv error, wait...."); | |
sleep(1); | |
continue; | |
} | |
} | |
else | |
{ | |
printf("buff=%s\n",buff); | |
} | |
break; | |
} | |
//发送数据 | |
while(1) | |
{ | |
if(send(new_fd,buff,strlen(buff),0) < 0) | |
{ | |
if(errno==EWOULDBLOCK) | |
{ | |
perror("send error, wait...."); | |
sleep(1); | |
continue; | |
} | |
} | |
else | |
{ | |
printf("buff=%s\n",buff); | |
} | |
break; | |
} | |
close(new_fd); | |
return 0; | |
} | |
//父进程关闭new_fd | |
close(new_fd); | |
} | |
close(sockfd); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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> | |
#include <unistd.h> | |
int main(int argc,char *argv[]) | |
{ | |
if(argc!=3) | |
{ | |
printf("%s: input IP & port\n",argv[0]); | |
return 1; | |
} | |
int sockfd,numbytes; | |
char buf[100] = "hello world"; | |
struct hostent *he; | |
struct sockaddr_in their_addr; | |
//将基本名字和地址转换 | |
he = gethostbyname(argv[1]); | |
//建立一个TCP套接口 | |
if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) | |
{ | |
perror("socket"); | |
exit(1); | |
} | |
//初始化结构体,连接到服务器的2323端口 | |
their_addr.sin_family = AF_INET; | |
their_addr.sin_port = htons(atoi(argv[2])); | |
their_addr.sin_addr = *((struct in_addr *)he->h_addr); | |
bzero(&(their_addr.sin_zero),8); | |
//和服务器建立连接 | |
if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr))==-1) | |
{ | |
perror("connect"); | |
exit(1); | |
} | |
//向服务器发送字符串 | |
if(send(sockfd,buf,strlen(buf),0)==-1) | |
{ | |
perror("send"); | |
exit(1); | |
} | |
memset(buf,0,sizeof(buf)); | |
//接受从服务器返回的信息 | |
if((numbytes = recv(sockfd,buf,100,0))==-1) | |
{ | |
perror("recv"); | |
exit(1); | |
} | |
close(sockfd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment